Codefest 17 C. Helga Hufflepuff's Cup(树形DP)

来源:互联网 发布:禁止域名转出万网 编辑:程序博客网 时间:2024/06/16 01:05

题意:

在一棵树上进行涂色,总共有 m 种颜色(编号1m),其中编号为 k 的颜色为特殊颜色,如果树上一个节点染上了特殊颜色,则其邻居节点的颜色编号都应该<k,求在这棵树上染色总共有多少种方法,染上特殊颜色的节点的数目不超过 x 个。
n105, m109, x10

思路:

难点:状态定义 + 状态转移方程细节
比较明显的树形dp。
首先是状态定义,如果我们仅定义:
dp[u][i][0]u为根节点的子树,使用了i个特殊颜色,且该当前根节点没有使用特殊颜色;
dp[u][i][1]u为根节点的子树,使用了i个特殊颜色,且该当前根节点使用了特殊颜色;
你会发现转移的时候,dp[u][i][0] 是没有办法求出来的。。。
所以我们定义:
dp[u][i][0]u为根节点的子树,使用了i个特殊颜色,且该当前根节点颜色编号小于 k
dp[u][i][1]u为根节点的子树,使用了i个特殊颜色,且该当前根节点颜色编号等于 k
dp[u][i][2]u为根节点的子树,使用了i个特殊颜色,且该当前根节点颜色编号大于 k
所以转移的过程我们只需要根据限制条件来就可以了。。。
以求dp[u][i][0] 为例,枚举子节点的特殊颜色贡献值j(ji),此时子节点颜色编号可以取任意值,即总的方案数为:dp[u][ij][0](dp[v][j][0]+dp[v][j][1]+dp[v][j][2]),将这个值累加即可。

要注意的是,在u节点枚举 i 的时候,是从大往小枚举,因为这样可以确保我使用的dp[u][ij][0] 是来自前一个 u 的子节点计算后得到的值,如果从小往大枚举,那么这个值就会被覆盖掉。

代码:

#include <bits/stdc++.h>const int N = 100005, mo = 1000000007, X = 12;int h[N],f1[N][X],f2[N][X],f3[N][X],n,m,k,z,u,v,xb,ans,i;struct edge{    int to, next;}e[N<<1];inline void addedge(int u,int v){    e[++xb] = (edge){v,h[u]}, h[u] = xb;    e[++xb] = (edge){u,h[v]}, h[v] = xb;}void dfs(int x,int fa){    f1[x][1] = 1,f2[x][0] = z-1,f3[x][0] = m-z;    for(int i = h[x];i;i = e[i].next)        if(e[i].to!=fa)        {            dfs(e[i].to,x);            for(int j = k;j >= 0;-- j)            {                int s1 = 0, s2 = 0,s3 = 0;                for(int l = 0;l <= j;++ l)                {                    if(l<j) s1 = (s1 + 1ll*f1[x][j-l] * f2[e[i].to][l])%mo;                    s2 = (s2 + 1ll*f2[x][j-l] * (1ll*f1[e[i].to][l] + f2[e[i].to][l] + f3[e[i].to][l]))%mo;                    s3 = (s3 + 1ll*f3[x][j-l] * (1ll*f2[e[i].to][l] + f3[e[i].to][l]))%mo;                }                f1[x][j] = s1,f2[x][j] = s2,f3[x][j] = s3;            }        }}int main(){    scanf("%d%d",&n,&m);    for(i = 1;i < n;++ i)    {        scanf("%d %d", &u, &v);        addedge(u, v);    }    scanf("%d %d", &z, &k);    dfs(1, 0);    for(i = 0;i <= k;++ i) ans = (1ll*ans + f1[1][i] + f2[1][i] + f3[1][i]) % mo;    return printf("%d\n", ans), 0;}
阅读全文
0 0
原创粉丝点击