C. Helga Hufflepuff's Cup 树形dp 难
这个题目我感觉挺难的,想了好久也写了很久,还是没有写出来。
dp[i][j][k] 代表以 i 为根的子树中共选择了 j 个特殊颜色,且当前节点 i 的状态为 k 的染色方案数。
- k=0 ,代表当前节点 i 的颜色值小于 K 。
- k=1,代表当前节点 i 的颜色值等于 K 。
- 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 难的更多相关文章
- Codeforces 855C - Helga Hufflepuff's Cup
855C - Helga Hufflepuff's Cup 题意 要求构建一棵树,树上至多可以存在 \(x\) 个权值为 \(k\) 的重要点,且与重要点连边的点的权值必须小于 \(k\),问有多少种 ...
- Helga Hufflepuff's Cup CodeForces - 855C
Helga Hufflepuff's Cup CodeForces - 855C 题意:给一棵n个节点的树,要给每一个节点一个附加值,附加值可以为1-m中的一个整数.要求只能有最多x个节点有附加值k. ...
- Codeforces 855C. Helga Hufflepuff's Cup----树形DP
z最近在学习树形DP...好难啊. 在cf上找到了一题c题当模版马克一下. 题目不贴了..>>http://codeforces.com/problemset/problem/855/C& ...
- codeforces:Helga Hufflepuff's Cup
题目大意:有一个包含n个顶点的无向无环连通图G,图中每个顶点都允许有一个值type,type的范围是1~m.有一个特殊值k,若一个顶点被赋值为k,则所有与之相邻的顶点只能被赋小于k的值.最多有x个顶点 ...
- 【DP】【CF855C】 Helga Hufflepuff's Cup
Description 给你一个树,可以染 \(m\) 个颜色,定义一个特殊颜色 \(k\) , 要求保证整棵树上特殊颜色的个数不超过 \(x\) 个.同时,如果一个节点是特殊颜色,那么它的相邻节点的 ...
- 855C Helga Hufflepuff's Cup
传送门 题目大意 给你一棵树,可以染m种颜色,现定义一种特殊的颜色K,一棵树上最多能有x个特殊颜色.如果一个节点为特殊颜色,那么他相邻的节点的值只能选比K小的颜色,问一共有多少种染色方案. 分析 不难 ...
- 【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup
[链接]h在这里写链接 [题意] k是最高级别的分数,最高界别的分数最多只能有x个. 1<=k<=m; 和k相邻的点的分数只能小于k; n个点的树,问你每个 ...
- 8VC Venture Cup 2016 - Final Round (Div. 1 Edition) E - Preorder Test 树形dp
E - Preorder Test 思路:想到二分答案了之后就不难啦, 对于每个答案用树形dp取check, 如果二分的值是val, dp[ i ]表示 i 这棵子树答案不低于val的可以访问的 最多 ...
- VK Cup 2012 Round 1 D. Distance in Tree (树形dp)
题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...
随机推荐
- Linux C++ 网络编程学习系列(4)——多路IO之epoll基础
epoll实现多路IO 源码地址:https://github.com/whuwzp/linuxc/tree/master/epoll 源码说明: server.cpp: 监听127.1:6666,功 ...
- synchronized 的真正含义
@synchronized 锁的永远是对象 ,只针对于对象,只能锁对象,常量等是不能加synchronized,一旦加编译也不会通过 @synchronized 锁对象中的非static 就是锁调用该 ...
- 第十三节:telnetlib、redis、threading模块
telnetlib模块案例: import telnetlib,re class TelnetInfo(): def telnetdo(self, host, port, command): tn = ...
- 【three.js第四课】自定义材料、贴图。
1.先去下载6张不同的图片素材放到项目中. 2.在[three.js第三课]的代码基础上添加自定义的材料 //自定义材料 cubeMaterial 数组 //map:用于加载图片,THREE.Text ...
- stand up meeting 12/22/2015 && 用户体验收录
part 组员 工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 完善页面切换,尝试子页面设计 4 完善页面切换和子页面 ...
- Flask接口开发过程中的心得2019.10.03
完善了一下慕课网实战中的post接口开发,得到了一些进步: 代码如下: #coding=utf-8 from flask import Flask from flask import request ...
- python selenium模块 css定位
selenium是python的非标准库,使用时需要下载安装 安装命令 pip install selenium selenium是python的自动化测试模块,可以模拟浏览器的行为 所以在使用之前 ...
- 【山外笔记-SVN命令】svnlook命令详解
本文打印版问文件下载地址 [山外笔记-SVN命令]svnlook命令详解-打印版.pdf 一.命令简介 svnlook是检验Subversion版本库不同方面的命令行工具,不会对版本库有任何修改,只是 ...
- linux之cat 操作
1.查看或创建 cat 1.txt #如果目录有这个文件则会打开查看,没有则会创建 2.压缩空白 cat 1.txt 我是第一行 我是第二 行 cat -bs 1.txt # 变成 cat 1.txt ...
- 通过Java + selenium +testNG + Page Objects 设计模式 实现页面UI的自动化
Page Objects 设计模式 简单的讲,类似与Java面向对象编程,把每个页面都抽象为一个对象类,将页面元素的定位.业务逻辑操作分离开,然后我们可以通过testNG实现业务流程的控制 与 测试 ...