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;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务