比较裸的依赖背包,但是想状态还是想了好久
转移时由于边界问题,虽然可以倒序转移,但当容量为0|1的时候,由于有初始值的存在
很难再原dp数组上进行修改,所以额外用tmp数组来保存修改后的值
#include<bits/stdc++.h> #include<vector> using namespace std; #define mod 1000000007 #define ll long long #define maxn 100005 vector<int>G[maxn]; ll dp[maxn][11][3],n,m,k,x; void dfs(int u,int pre){ dp[u][0][0]=k-1;dp[u][1][1]=1;dp[u][0][2]=m-k;//先确定初始态:结点u本身的取值 for(int i=0;i<G[u].size();i++) if(G[u][i]!=pre)dfs(G[u][i],u); for(int i=0;i<G[u].size();i++){ ll tmp[11][3]={};//临时数组用来存储节点u的答案 int v=G[u][i]; if(v==pre)continue; for(int j=x;j>=0;j--) for(int l=0;l<=j;l++){ tmp[j][0]=(tmp[j][0]+(dp[v][l][0]+dp[v][l][1]+dp[v][l][2])*dp[u][j-l][0])%mod; tmp[j][1]=(tmp[j][1]+dp[v][l][0]*dp[u][j-l][1])%mod; tmp[j][2]=(tmp[j][2]+(dp[v][l][0]+dp[v][l][2])*dp[u][j-l][2])%mod; } for(int j=0;j<=x;j++) for(int l=0;l<3;l++) dp[u][j][l]=tmp[j][l]; } } int main(){ cin>>n>>m; int u,v; for(int i=1;i<n;i++){ cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } cin>>k>>x; dfs(1,0); ll ans=0; for(int i=0;i<=x;i++) ans=(ans+dp[1][i][0]+dp[1][i][2])%mod; for(int i=1;i<=x;i++) ans=(ans+dp[1][i][1])%mod; cout<<ans<<endl; }