zoukankan      html  css  js  c++  java
  • NC13611-树-(dp)

    链接:https://ac.nowcoder.com/acm/problem/13611
    来源:牛客网

    题目描述

    shy有一颗树,树有n个结点。有k种不同颜色的染料给树染色。一个染色方案是合法的,当且仅当对于所有相同颜色的点对(x,y),x到y的路径上的所有点的颜色都要与x和y相同。请统计方案数。

    输入描述:

    第一行两个整数n,k代表点数和颜色数;
    接下来n-1行,每行两个整数x,y表示x与y之间存在一条边;

    输出描述:

    输出一个整数表示方案数(mod 1e9+7)。
    示例1

    输入

    复制 
    4 3
    1 2
    2 3
    2 4

    输出

    复制 
    39

    备注:

    对于30%的数据,n≤10, k≤3;
    对于100%的数据,n,k≤300。

     

    一直以为树的题目要用dfs解决,难得见到不用的。

    n个点的树,看作一张连通图,任意两点路径上的点要相同颜色,也就是两点间的一片都要相同颜色,看作是一个连通分量,颜色有k种,任选多少种涂都行,在颜色上不做要求。

    对于一个连通图,加上一个点,这个点的涂色方法,可以选择旧颜色和新颜色。

    dp[i][j]表示i个点的联通图用j种颜色涂色的方案数量

    对于第i个点,涂旧颜色即dp[i-1][j],涂新颜色即dp[i-1][j-1]*(k-(j-1));

    dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(k-(j-1));

    最后将n个点的连通图加起来就好。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    const int p=1e9+7;
    ll dp[305][305];
    
    int main()///NC13611
    {
        int n,k;
        scanf("%d%d",&n,&k);
        memset(dp,0,sizeof(dp));
        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]%=p;
            }
        }
        ll ans=0;
        for(int i=1;i<=k;i++)
            ans=(ans+dp[n][i])%p;
        printf("%lld
    ",ans);
    
        return 0;
    }

    数论解法:

     

  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/12667316.html
Copyright © 2011-2022 走看看