Codeforces 486D Valid Sets(暴力)

题目链接:Codeforces 486D Valid Sets

题目大意:给定一棵树,每个节点有个权值,现在要选定一些节点,要求非空,并且maxVal-minVal不大于d。问说有多

少种选择方法。

解题思路:枚举每个节点作为根节点,默认根节点为权值最大的节点,然后各个孩子节点用乘法原理即可。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 2005;

int N, D, W[maxn];
vector<int> G[maxn];

ll dfs(int u, int f, int rt) {
    int n = G[u].size();
    ll ret = 1;

    for (int i = 0; i < n; i++) {
        int v = G[u][i];

        if (v == f || W[rt] < W[v] || (W[rt] == W[v] && v > rt) || W[rt] - W[v] > D)
            continue;
        ret = ret * (dfs(v, u, rt) + 1) % mod;
    }
    return ret;
}

int main () {
    scanf("%d%d", &D, &N);
    for (int i = 1; i <= N; i++)
        scanf("%d", &W[i]);
    int u, v;
    for (int i = 1; i < N; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    ll ans = 0;
    for (int i = 1; i <= N; i++)
        ans = (ans + dfs(i, -1, i)) % mod;
    printf("%lld\n", ans);
    return 0;
}
时间: 2024-11-05 18:54:15

Codeforces 486D Valid Sets(暴力)的相关文章

Codeforces 486D Valid Sets:Tree dp【n遍O(n)的dp】

题目链接:http://codeforces.com/problemset/problem/486/D 题意: 给你一棵树,n个节点,每个节点的点权为a[i]. 问你有多少个连通子图,使得子图中的max(a[i]) - min(a[i]) <= d. ps.连通子图的定义: 如果一个点集V为一个连通子图,则对于任意两点a,b∈V,有a到b路径上的所有点u∈V. 题解: 因为要保证max(a[i]) - min(a[i]) <= d,所以可以人为地选出一个点rt作为点权最大的点. 这样在求以rt

CodeForces 486D Valid Sets

题意: 给定一棵n(2000)个节点的树  每个节点上有个数字  问  有多少棵子树满足树中最大数字与最小数字的差不超过d 思路: 根据数据猜复杂度可能为n^2  想到尝试树形dp 假如枚举现在树中的最大值  那么最小值可以求出  这时不在数值范围内的节点都可以标记掉 那么假设这个最大值的点我一定选取  那么就可以dp出一定选这个点的情况下子树的种类数 假设u是父节点  v是子节点  那么已知dp[u]=dp[u]*dp[v]  特殊的v如果是叶子  那么dp[v]=2  即可选可不选  如果u

Codeforces 486D Valid Sets 树形dp+计数

题目链接:点击打开链接 题意:给定常数d 和 n,表示n个点的树,每个点有点权 问:有多少个点集使得点集中的点两两可达且最大点权-最小点权<=d 思路: 对于每个点,计算包含这个点且这个点作为点集中的最小点权时的个数,枚举每个点. import java.io.PrintWriter; import java.text.DecimalFormat; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.

Codeforces Round #277 (Div. 2) D. Valid Sets DP

D. Valid Sets As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are given an integer d and a tree consisting of n nodes. Each node i has a value ai associated with it. We call a set S of tree nodes valid if

Codeforces 57C Array dp暴力找规律

题目链接:点击打开链接 先是计算非递增的方案, 若非递增的方案数为x, 则非递减的方案数也是x 答案就是 2*x - n 只需求得x即可. 可以先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元即可. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #def

Codeforces 468B Two Sets(二分图匹配)

题目链接:Codeforces 468B Two Sets 题目大意:给出n个数,要求将n个数分配到两个集合中,集合0中的元素x,要求A-x也再0中,同理1集合. 解题思路:类似二分图匹配的方法. #include <cstdio> #include <cstring> #include <map> #include <stack> #include <algorithm> using namespace std; const int maxn

Codeforces 57B Martian Architecture 暴力||线段树

题目链接:点击打开链接 题意:n长的序列(初始全为0) m个操作 k个查询 下面m个操作[l,r] h 代表 a[l] +=h; a[l+1] += h+i; a[l+i] += h+i;  l<=i<=r 然后问k个位置的和 因为k<=100 所以直接暴力也可以 ----------------------- 如果k<=100000 也是可以做的 只需要给区间记录一个标记lazy,表示从左端点开始 l, l+1, l+i ··· l+r 而向下更新时, 左区间则直接更新, 右区间

Codeforces Round #277 (Div. 2)Valid Sets 树DP

题意:给出一棵树,并给出每个节点上的权值,求有多少个连通子块的最大值与最小值的差不超过d. 对于每个顶点建立一颗树,然后找比它价值大的   或者   价值相等且之前没有被当作顶点建立树的点,这样就避免重复了. dp[x]表示包涵x且以x为顶点的连通子树的个数,dp[x] = ∏ (dp[son[x]] + 1). 注意要用long long . #include<iostream> #include<iostream> #include<cstdio> #include

codeforces 724B Batch Sort(暴力-列交换一次每行交换一次)

题目链接:http://codeforces.com/problemset/problem/724/B 题目大意: 给出N*M矩阵,对于该矩阵有两种操作: (保证,每行输入的数是 1-m 之间的数且不重复) 1.交换两列,对于整个矩阵只能操作一次 2.每行交换两个数. 交换后是否可以使每行都是1-m 数字递增. 解题思路: 1.得到矩阵后先判断,是否每行可以交换两个数可以得到递增的矩阵,如果可以则输出“YES”. 2.暴力交换两列,交换两列后,判断每行是否可以交换两个数得到递增的矩阵,如果可以则