BZOJ 5314: [Jsoi2018]潜入行动
树形DP
#include<cstdio> #include<algorithm> using namespace std; const int mod=1e9+7; int cnt,n,k,F[100005][105][2][2],last[100005],sz[100005],G[105][2][2]; struct node{ int to,next; }e[200005]; void add(int a,int b){ e[++cnt].to=b; e[cnt].next=last[a]; last[a]=cnt; } void dfs(int x,int fa){ sz[x]=1; F[x][0][0][0]=1,F[x][1][1][0]=1; for (int i=last[x]; i; i=e[i].next){ int V=e[i].to; if (V==fa) continue; dfs(V,x); for (int now=0; now<=min(sz[x],k); now++){ G[now][0][0]=F[x][now][0][0],F[x][now][0][0]=0; G[now][0][1]=F[x][now][0][1],F[x][now][0][1]=0; G[now][1][0]=F[x][now][1][0],F[x][now][1][0]=0; G[now][1][1]=F[x][now][1][1],F[x][now][1][1]=0; } for (int pre=0; pre<=min(sz[x],k); pre++) for (int now=0; now<=min(sz[V],k-pre); now++){ int To=pre+now; F[x][To][0][0]+=1ll*G[pre][0][0]*F[V][now][0][1]%mod; if (F[x][To][0][0]>mod) F[x][To][0][0]-=mod; F[x][To][0][1]+=1ll*G[pre][0][0]*F[V][now][1][1]%mod; if (F[x][To][0][1]>mod) F[x][To][0][1]-=mod; F[x][To][0][1]+=1ll*G[pre][0][1]*(F[V][now][0][1]+F[V][now][1][1])%mod; if (F[x][To][0][1]>mod) F[x][To][0][1]-=mod; F[x][To][1][0]+=1ll*G[pre][1][0]*(F[V][now][0][0]+F[V][now][0][1])%mod; if (F[x][To][1][0]>mod) F[x][To][1][0]-=mod; F[x][To][1][1]+=1ll*G[pre][1][0]*(F[V][now][1][0]+F[V][now][1][1])%mod; if (F[x][To][1][1]>mod) F[x][To][1][1]-=mod; F[x][To][1][1]+=1ll*G[pre][1][1]*(1ll*F[V][now][0][0]+F[V][now][0][1]+F[V][now][1][0]+F[V][now][1][1])%mod; if (F[x][To][1][1]>mod) F[x][To][1][1]-=mod; } sz[x]+=sz[V]; } } int main(){ scanf("%d%d",&n,&k); for (int i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(1,0); printf("%d\n",(F[1][k][0][1]+F[1][k][1][1])%mod); return 0; }