C. Helga Hufflepuff's Cup

这个题目我感觉挺难的,想了好久也写了很久,还是没有写出来。

dp[i][j][k] 代表以 i 为根的子树中共选择了 j 个特殊颜色,且当前节点 i 的状态为 k 的染色方案数。

  1. k=0 ,代表当前节点 i 的颜色值小于 K 。
  2. k=1,代表当前节点 i 的颜色值等于 K 。
  3. k=2,代表当前节点 i 的颜色值大于 K 。

但是这个dfs过程的处理我觉得很复杂。

我们需要一个数组来进行临时的存储。

tmp[i][k] 表示选了 i 个  状态为 j 的方案数。

先枚举这个点已经用了 i 个,然后枚举这个子节点可以加上 j 个

tmp[j + h][0] += dp[u][j][0] * (dp[v][h][0] + dp[v][h][1] + dp[v][h][2]) % mod;
tmp[j + h][0] %= mod;
tmp[j + h][1] += dp[u][j][1] * dp[v][h][0] % mod;
tmp[j + h][1] %= mod;
tmp[j + h][2] += dp[u][j][2] * (dp[v][h][0] + dp[v][h][2]) % mod;
tmp[j + h][2] %= mod;

然后每次再赋值回去,注意这个tmp的定义,tmp[i,j]是k有 i 个,状态为 j 的方案。

这个地方我觉得挺难想的,我是没有想到。

这个是对于每一个节点u,我们枚举它的子树,一开始这个dp[u] 的初始化要注意,

我们先考虑如果子树没有k,这个状态是怎么样的,因为只有这个状态我们是可以定下来的,如果有k,这种状态必须通过转移得来。

然后再枚举子树k的个数,再去更新这个节点u。

这里用了一点点的乘法原理,挺厉害的,我一开始想的是,枚举这个u的所有可能的k的数量,然后再去用背包,这个好像有点不对。

因为我们不是取最大的那个,而是取求组合数,应该枚举每一种可能,然后相乘,也有可能是我想的不太对。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 2e5 + ;
const int mod = 1e9 + ;
typedef long long ll;
struct node {
int v, nxt;
node(int v = , int nxt = ) :v(v), nxt(nxt) {}
}ex[maxn];
int head[maxn], cnt = ;
int n, m, k, x;
void init()
{
memset(head, -, sizeof(head));
cnt = ;
}
void add(int u,int v)
{
ex[cnt] = node(v, head[u]);
head[u] = cnt++;
ex[cnt] = node(u, head[v]);
head[v] = cnt++;
}
int num[maxn];
ll tmp[][];
ll dp[maxn][][];//注意这个dp的定义,dp[i,j,x]表示到i这个节点,子树用k的数量为j,x==0 表示这个节点小于k,1代表等于k,2代表大于k
void dfs(int u,int pre)
{
dp[u][][] = k - ;
dp[u][][] = ;
dp[u][][] = m - k;
num[u] = ;
for (int i = head[u]; i != -; i = ex[i].nxt) {
int v = ex[i].v;
if (v == pre) continue;
dfs(v, u);
memset(tmp, , sizeof(tmp));
for (int j = ; j <= num[u]; j++) {
for (int h = ; h <= num[v]; h++) {
if (j + h > x) continue;
tmp[j + h][] += dp[u][j][] * (dp[v][h][] + dp[v][h][] + dp[v][h][]) % mod;
tmp[j + h][] %= mod;
tmp[j + h][] += dp[u][j][] * dp[v][h][] % mod;
tmp[j + h][] %= mod;
tmp[j + h][] += dp[u][j][] * (dp[v][h][] + dp[v][h][]) % mod;
tmp[j + h][] %= mod;
}
}
num[u] = min(x, num[u] + num[v]);
for (int j = ; j <= num[u]; j++) {
for (int h = ; h < ; h++) {
dp[u][j][h] = tmp[j][h];
}
}
}
} int main()
{
init();
scanf("%d%d", &n, &m);
for(int i=;i<=n-;i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
ll ans = ;
scanf("%d%d", &k, &x);
dfs(, -);
for (int i = ; i <= x; i++) {
for (int j = ; j < ; j++) {
ans = (ans + dp[][i][j]) % mod;
}
}
printf("%lld\n", ans);
return ;
}

C. Helga Hufflepuff's Cup 树形dp 难的更多相关文章

  1. Codeforces 855C - Helga Hufflepuff's Cup

    855C - Helga Hufflepuff's Cup 题意 要求构建一棵树,树上至多可以存在 \(x\) 个权值为 \(k\) 的重要点,且与重要点连边的点的权值必须小于 \(k\),问有多少种 ...

  2. Helga Hufflepuff's Cup CodeForces - 855C

    Helga Hufflepuff's Cup CodeForces - 855C 题意:给一棵n个节点的树,要给每一个节点一个附加值,附加值可以为1-m中的一个整数.要求只能有最多x个节点有附加值k. ...

  3. Codeforces 855C. Helga Hufflepuff's Cup----树形DP

    z最近在学习树形DP...好难啊. 在cf上找到了一题c题当模版马克一下. 题目不贴了..>>http://codeforces.com/problemset/problem/855/C& ...

  4. codeforces:Helga Hufflepuff's Cup

    题目大意:有一个包含n个顶点的无向无环连通图G,图中每个顶点都允许有一个值type,type的范围是1~m.有一个特殊值k,若一个顶点被赋值为k,则所有与之相邻的顶点只能被赋小于k的值.最多有x个顶点 ...

  5. 【DP】【CF855C】 Helga Hufflepuff's Cup

    Description 给你一个树,可以染 \(m\) 个颜色,定义一个特殊颜色 \(k\) , 要求保证整棵树上特殊颜色的个数不超过 \(x\) 个.同时,如果一个节点是特殊颜色,那么它的相邻节点的 ...

  6. 855C Helga Hufflepuff's Cup

    传送门 题目大意 给你一棵树,可以染m种颜色,现定义一种特殊的颜色K,一棵树上最多能有x个特殊颜色.如果一个节点为特殊颜色,那么他相邻的节点的值只能选比K小的颜色,问一共有多少种染色方案. 分析 不难 ...

  7. 【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup

    [链接]h在这里写链接 [题意]     k是最高级别的分数,最高界别的分数最多只能有x个.     1<=k<=m;     和k相邻的点的分数只能小于k;     n个点的树,问你每个 ...

  8. 8VC Venture Cup 2016 - Final Round (Div. 1 Edition) E - Preorder Test 树形dp

    E - Preorder Test 思路:想到二分答案了之后就不难啦, 对于每个答案用树形dp取check, 如果二分的值是val, dp[ i ]表示 i 这棵子树答案不低于val的可以访问的 最多 ...

  9. VK Cup 2012 Round 1 D. Distance in Tree (树形dp)

    题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...

随机推荐

  1. ${param.pageNo}是什么意思?

    1.${param.id}与request.getParameter("id"):功能相同2.param.id获取输入的参数id,也可理解为的是form或者div表单里的ID. r ...

  2. Julia基础语法字符和字符串

    1.Julia字符串  2.字符

  3. Daily Scrum 12/16/2015

    Process: Dong&Minlong : 继续对Oxford Speech 接口进行调试,并且完成了相应工作的转接. Yandong@Zhaoyang: 完成了对一些Bug的修复工作,程 ...

  4. 【jmeter】JDBC请求循环调用的问题

    今天使用jdbc请求从数据库取数据,多次请求使用了循环控制器,但是结果第一个jdbc请求返回值正确,第二次请求返回值为空. 1.从其他博客中得知,需要在jdbc connection configur ...

  5. Eureka源码分析

    源码流程图 先上图,不太清晰,抱歉 一.Eureka Server源码分析 从@EnableEurekaServer注解为入口,它是一个标记注解,点进去看 注解内容如下 /** * 激活Eureka服 ...

  6. 详解 Lambda表达式

    Lambda表达式 概述: Lambda 是一个匿名函数, 我们可以把 Lambda表达式理解为是一段可以传递的代码 (将代码像数据一样进行传递) 可以写出更简洁.更灵活的代码. 作为一种更紧凑的代码 ...

  7. 零基础的学习者应该怎么开始学习呢?Python核心知识学习思维分享

    近几年,Python一路高歌猛进,成为最受欢迎的编程语言之一,受到无数编程工作者的青睐. 据悉,Python已经入驻部分小学生教材,可以预见学习Python将成为一项提高自身职业竞争力的必修课.那么零 ...

  8. Intellij IDEA 基础设置,个性化设置,好用的设置→_→

    Intellij IDEA 个性化设置 Appearance & Behavior 外观和行为 Keymap 快捷键 Editor 编辑器设置 Plugins 插件 Version Contr ...

  9. Vue 3.0 Composition API - 中文翻译

    Composition API 发布转载请附原文链接 https://www.cnblogs.com/zgh-blog/articles/composition_api.html 这两天初步了解了下 ...

  10. echarts迁徙图

    前段时间在echarts社区,看见别人写的echarts迁徙图,学习并也写了一个 预览地址: https://gallery.echartsjs.com/editor.html?c=xYS-YtzOa ...