1. 程式人生 > >Codeforces 855C. Helga Hufflepuff's Cup----樹形DP

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

需要 ring ble 遞歸 mem sizeof ces pac eof

z最近在學習樹形DP...好難啊。

在cf上找到了一題c題當模版馬克一下。

題目不貼了。。>>http://codeforces.com/problemset/problem/855/C<<

題目的意思就是給你一棵有n個節點的樹,m個關系,每個節點需要上色,一共有K種顏色,其中有一個最大色,與他相鄰的節點只能上比他“小”的顏色。並且最多有X個節點可以染最大色。求問染色方法有多少種。

代碼如下:

#include<vector>
#include<algorithm>
#include<iostream>
#include<string.h>
#include
<math.h> using namespace std; const int mod=1e9+7; int n,m,K,X; vector<int> e[100010];//用來存儲樹枝(雙向) long long dp[100010][12][3];//dp主體,分別表示節點、選擇最大色的節點數,最後一個空的0,1,2分別表示“選比最大色小的顏色時”
//
“選最大色時”、“選比最大色大的顏色時”

int sz[100010]={0};//表示遞歸到該節點時已選最大色的數目
int t[12][3];

int sz[100010]={0};
int t[12][3];
long long dfs(int x,int pre)
{
dp[x][0][0]=K-1;
dp[x][1][1]=1;
dp[x][0][2]=m-K;
sz[x]=1;
int i,xx,j,k;
for(i=0;i<e[x].size();i++)
{
xx=e[x][i];
if(xx==pre) continue;
dfs(xx,x);
memset(t,0,sizeof(t));
for(j=0;j<=sz[x];j++)
for(k=0;k<=sz[xx];k++)
{
if(j+k>X) continue;
t[j+k][0]=(t[j+k][0]+(dp[x][j][0]*(dp[xx][k][0]+dp[xx][k][1]+dp[xx][k][2]))%mod)%mod;
t[j+k][1]=(t[j+k][1]+(dp[x][j][1]*dp[xx][k][0]%mod))%mod;
t[k+j][2]=(t[k+j][2]+(dp[x][j][2]*(dp[xx][k][0]+dp[xx][k][2])%mod))%mod;
}
sz[x]=min(sz[x]+sz[xx],X);
for(j=0;j<=sz[x];j++)
for(k=0;k<=2;k++)
{
dp[x][j][k]=t[j][k];
}
}
}
int main()
{
int i,j,k,q,w;
while(cin>>n>>m)
{
long long ans=0;
for(i=1;i<=n;i++) e[i].clear();
for(i=1;i<n;i++)
{
cin>>q>>w;
e[q].push_back(w);
e[w].push_back(q);
}
cin>>K>>X;
dfs(1,-1);
for(j=0;j<=sz[1];j++)
for(k=0;k<=2;k++)
ans=(ans+dp[1][j][k])%mod;
cout<<ans<<endl;
}
}

 

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