Codeforces Round #277(Div. 2)Valid Sets 트리 DP
6047 단어 codeforces
각 정점에 나무를 세운 다음에 그보다 가치가 크거나 가치가 같고 이전에 정점으로 나무가 세워지지 않은 점을 찾으면 중복을 피할 수 있다.
dp[x]는 x를 포함하고 x를 정점으로 하는 연통자 나무의 개수를 나타낸다. dp[x]=∏(dp[son[x]]]+1).
롱롱 주의.
#include<iostream>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long LL;
LL d;
const LL maxn = 2222;
const LL mod = 1000000007;
struct Node
{
LL next; LL to;
}e[maxn * 2];
LL len;
LL head[maxn];
LL dp[maxn];
LL father[maxn];
LL vis[maxn];
void add(LL from, LL to)
{
e[len].to = to;
e[len].next = head[from];
head[from] = len++;
}
void build(LL root, LL pre)
{
father[root] = pre;
for (LL i = head[root]; i != -1; i = e[i].next){
LL cc = e[i].to;
if (cc == pre) continue;
build(cc, root);
}
}
LL val[maxn];
void dfs(LL x, LL root)
{
dp[x] = 0; LL ans = 1;
for (LL i = head[x]; i != -1; i = e[i].next){
LL cc = e[i].to;
if (cc == father[x])continue;
if (val[cc] == val[root] && vis[cc]) continue;
if (val[cc]<val[root] || val[cc] - val[root]>d) continue;
// prLLf("%I64d %I64d
",cc,val[cc]);system("pause");
dfs(cc, root);
ans *= dp[cc] + 1; ans %= mod;
}
dp[x] += ans; dp[x] %= mod;
}
int main()
{
LL n;
cin >> d >> n;
len = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
for (LL i = 1; i <= n; i++)
scanf("%I64d", &val[i]);
for (LL i = 1; i<n; i++){
LL a; LL b;
scanf("%I64d%I64d", &a, &b);
add(a, b); add(b, a);
}
LL ans = 0;
for (LL i = 1; i <= n; i++){
build(i, i); dfs(i, i);
ans += dp[i]; vis[i] = 1;
ans %= mod;
// prLLf("%I64d
",dp[i]);
}
cout << ans << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Codeforces Round #715 Div. 2C The Sports Festival: 구간 DP전형구간 DP의 초전형. 이하, 0-indexed. 입력을 정렬하여 어디서나 시작하고 최적으로 좌우로 계속 유지하면 좋다는 것을 알 수 있습니다. {2000})$의 주문이 된다. 우선, 입력을 소트하여 n개의 요소를 $...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.