Codeforces 461B Appleman and Tree:Tree dp
题目链接:http://codeforces.com/problemset/problem/461/B
题意:
给你一棵树(编号从0到n-1,0为根节点),每个节点有黑白两种颜色,其中黑色节点有k+1个。
现在让你删掉k条边,使得这棵树变成k+1个连通块,并且要保证每个连通块中有且仅有一个黑色节点。
问你删边的方案有多少种。
题解:
表示状态:
dp[i][0/1] = numbers
表示在节点i所在的连通块中有(1)或没有(0)黑色节点时,节点i的子树的删边方法数
因为总要保证每个连通块中有且仅有一个黑点,所以最后一定删了恰好k条边,并不用记录当前删了多少边。
找出答案:
ans = dp[0][1]
最终根所在连通块中一定有且仅有一个黑点。
如何转移:
将删边的过程反过来考虑。
将节点i连向它的儿子的边一条条删去,相当于:
i本身没有儿子,然后将一棵棵子树添加为它的儿子,同时保证合法。
那么最终的方案取决于三个条件:
(1)i所在的连通块(简称块i)是否有黑点
(2)son所在的连通块(简称块son)是否有黑点
(3)是否删去边(i,son)
分情况讨论:
(1)块i有黑点
a. 块son有黑点,此时只能将边删去,最终的块i有黑点
b. 块son全是白,此时只能保留这条边,最终的块i有黑点
(2)i是白色
a. 块son有黑点,此时删边或不删都可以:
I. 删边,最终的块i全是白
II. 不删,最终的块i有黑点
b. 块son全是白,此时只能保留这条边,最终的块i全是白
综上:
dp[now][1] = dp[son][0]*dp[now][1] + dp[son][1]*(dp[now][1]+dp[now][0])
dp[now][0] = (dp[son][0]+dp[son][1])*dp[now][0]
边界条件:
dp[i][c[i]]=1
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 100005
#define MOD 1000000007 using namespace std; int n;
int c[MAX_N];
long long dp[MAX_N][];
vector<int> edge[MAX_N]; void read()
{
cin>>n;
int x;
for(int i=;i<n;i++)
{
cin>>x;
edge[x].push_back(i);
}
for(int i=;i<n;i++)
{
cin>>c[i];
}
} void dfs(int now)
{
dp[now][c[now]]=;
for(int i=;i<edge[now].size();i++)
{
int temp=edge[now][i];
dfs(temp);
long long blk=dp[now][];
long long wht=dp[now][];
dp[now][]=(dp[temp][]*blk+dp[temp][]*(blk+wht))%MOD;
dp[now][]=(dp[temp][]+dp[temp][])*wht%MOD;
}
} void work()
{
dfs();
cout<<dp[][]<<endl;
} int main()
{
read();
work();
}
Codeforces 461B Appleman and Tree:Tree dp的更多相关文章
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
- Codeforces 461B - Appleman and Tree 树状DP
一棵树上有K个黑色节点,剩余节点都为白色,将其划分成K个子树,使得每棵树上都仅仅有1个黑色节点,共同拥有多少种划分方案. 个人感觉这题比較难. 如果dp(i,0..1)代表的是以i为根节点的子树种有0 ...
- Codeforces 461B Appleman and Tree
http://codeforces.com/problemset/problem/461/B 思路:dp,dp[i][0]代表这个联通块没有黑点的方案数,dp[i][1]代表有一个黑点的方案数 转移: ...
- Codeforces 461B. Appleman and Tree[树形DP 方案数]
B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- CodeForces 461B Appleman and T
题目链接:http://codeforces.com/contest/461/problem/B 题目大意: 给定一课树,树上的节点有黑的也有白的,有这样一种分割树的方案,分割后每个子图只含有一个黑色 ...
- Codeforces 432D Prefixes and Suffixes:KMP + dp
题目链接:http://codeforces.com/problemset/problem/432/D 题意: 给你一个字符串s,让你找出所有既是前缀又是后缀的子串,并输出它们分别出现了多少次. 题解 ...
- Codeforces 148D Bag of mice:概率dp 记忆化搜索
题目链接:http://codeforces.com/problemset/problem/148/D 题意: 一个袋子中有w只白老鼠,b只黑老鼠. 公主和龙轮流从袋子里随机抓一只老鼠出来,不放回,公 ...
- Codeforces 366C Dima and Salad:背包dp
题目链接:http://codeforces.com/problemset/problem/366/C 题意: 有n个物品,每个物品有两个属性a[i]和b[i]. 给定k,让你选出一些物品,使得 ∑ ...
- Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...
随机推荐
- CAN协议学习(二)MCAN控制器介绍
更多细节请参看MCAN2文档mcan2_ps.pdf. 一.MCAN2简介 MCAN2是Mentor公司开发的一个CAN2.0网络控制器的软核,初版2001年末版2006年.MCAN 2控制器实现了B ...
- 跟我一起写 Makefile(三)[转]
原文链接 http://bbs.chinaunix.net/thread-408225-1-1.html(出处: http://bbs.chinaunix.net/) make 的运行—————— 一 ...
- iOS 字符属性NSAttributedString描述【转载】
/* 字符属性 字符属性可以应用于 attributed string 的文本中. NSString *const NSFontAttributeName;(字体) NSString *const N ...
- C指针解析 ------ 指针的算术运算
本文是自己学习所做笔记.欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020 指针是一个特殊的变量,表示一个地址,而地址能够上减去或加上一个整数,从而能够表示 ...
- Cannot open channel to 3 at election address :3888 java.net.ConnectException: Connection refused (Connection refused)
关于Linux中搭建分布式时可能遇到的问题 这个问题来自于今天安装zookeeper时踩的一个大坑,害的我花了一天时间.在搭建zookeeper的分布式时,往往要进行这样的配置: server.1=h ...
- openWRT自学---对官方的开发指导文档的解读和理解 记录1:编译一个package
针对的是:http://kamikaze.openwrt.org/docs/openwrt.html#x1-390002 1.If you want, you can also modify the ...
- hdu3068 最长回文(manacher 算法)
题意: 给定字符串.求字符串中的最长回文序列 解题思路: manacher 算法 时间复杂度:O(N) 代码: #include <cstdio> #include <cstring ...
- Linux进程间通信(三) - 信号
什么是信号 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程间通 ...
- 我为什么要学习jquery
因为jquery很强大,很少的代码实现更多的功能.
- python并发编程之多进程、多线程、异步和协程
一.多线程 多线程就是允许一个进程内存在多个控制权,以便让多个函数同时处于激活状态,从而让多个函数的操作同时运行.即使是单CPU的计算机,也可以通过不停地在不同线程的指令间切换,从而造成多线程同时运行 ...