树
树
https://ac.nowcoder.com/acm/problem/13611
此题有点花里胡哨,还真的不好想,但是一想到就会非常简单了。
我还是想了很久才弄明白。所以分享给大家。
此题就是连通块 ,如果选择x-y路径,那么所有节点必须一样,但是如果颜料足够的话 ,是不是我们每一个都可以分一个颜色,那么动态规划的味道就来了。
特别注意 此题无论你的树是什么样子的它一定是一个连通块,所有图不用存,直接搞他就完了。
首先,开一个DP[i][j];
什么意思呢? 就是当前第i个节点,使用了j种颜色。
我们可以分成2种情况。
第一,我和父亲节点一样,那么当前的就是dp[i-1][j];继承父亲节点的种类。
第二种,我和父亲的不一样,那么是不是就是dp[i-1][j-1]的情况,但是没有完,既然和父亲的不一样 是不是还剩下k-(j-1)种颜色没选择 ,是不是我们就可以上去,然后就是dp[i-1][j-1](j-(k-1));
由此,我们就做出来了,主要开LL,然后数据范围,别和我一样开小了,一直查,TCL。
还有更厉害的大佬是组合数做的 ,嘿嘿,实在是想不到。
#include <bits/stdc++.h> #define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define debug(x) cout << #x << ": " << x << endl; #define debug1(x) cout<<"xxx"<<endl; #define ll long long #define ull unsigned long long #pragma GCC optimize("Ofast","inline","-ffast-math") #pragma GCC target("avx,sse2,sse3,sse4,mmx") using namespace std; const int maxx=1e6+100; const int mod=1e9+7; int main() { ll n,k; cin>>n>>k; { for(int i=1;i<n;i++) { int a,b; cin>>a>>b; } ll dp[400][330]; dp[0][0]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=k;j++) { dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(k-j+1); dp[i][j]%=mod; } } ll ans=0; for(int i=1;i<=k;i++) ans+=dp[n][i]%mod,ans%=mod; cout<<ans<<endl; } return 0; }