http://www.nowcoder.com/questionTerminal/86fc8c46a8ce4c1fba763b8cf311f805

题目意思是用k个点把一个有n个节点的树染色,然后的地方必须联通,求有多少方案数?
下面给大家介绍两种做法..
图片说明
做法1:切边表示染色用的颜色个数,比如我要用3种颜色染色,那么我就只要考虑切2条边,比如切2-4,和3和7这是一种方案,那么,考虑树,一共n个点,一共n-1条边,我可以用k种颜色染色,那么就是切k-1条边.也就是选k-1条边.那么答案就是:
Cn-1 0+Cn-1 1+Cn-1 2+Cn-1 3+...+Cn-1 k-3+Cn-1 k-2+Cn-1 k-1的和..然后考虑染色,假如我现在切的是i条边,那么,我选颜色总数就是A(k,i+1). 代码如下:

#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb push_back
#define inf 132913423039
typedef long long ll;
const ll mod=1e9+7;
const ll N=2e3+5;
const ll M=2e4+5;
const double eps=1e-7;
using namespace std;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b) { return a*b/gcd(a,b);    }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}
ll Inv(ll x)          { return qp(x,mod-2,mod);}
ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;}
ll A(ll n,ll m,ll mod){ll sum=1; for(int i=n;i>=n-m+1;i--) sum=(sum*i)%mod; return sum%mod;}
int main()
{
     ios;
     ll n,k,ans=0,x,y;
     cin>>n>>k;
     for(int i=0;i<n-1;i++)  cin>>x>>y;
     for(ll i=0;i<k;i++)
     {
         ans=(ans+(A(k,i+1,mod)*C(n-1,i))%mod)%mod;
     }
     cout<<ans<<endl;
     return 0;
}

做法2:
用dp来做.设dp[i][j]表示我染色了i个用了j种颜***r>图片说明
考虑我现在已经到了dp[7][3]了,那我现在是不是可以到dp[8][3]/dp[8][4]去,到dp[8][3]是不是就等于dp[7][3],而dp[8][4]是不是就等于dp[7][3](还可以染的颜色种数)..那么就是dp[8][4]=dp[7][3](k-3)+还有一种就是dp[7][4]上个7个格子染色4个继续下一个..对吧..由此我们可以推出方程就是:
dp[i][j]=dp[i-1][j-1]*(k-(j-1))+dp[i-1][j];
代码如下:

#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb push_back
#define inf 132913423039
typedef long long ll;
const ll mod=1e9+7;
const ll N=3e2+5;
const ll M=2e4+5;
const double eps=1e-7;
using namespace std;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b) { return a*b/gcd(a,b);    }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}
ll Inv(ll x)          { return qp(x,mod-2,mod);}
ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;}
ll A(ll n,ll m,ll mod){ll sum=1; for(int i=n;i>=n-m+1;i--) sum=(sum*i)%mod; return sum%mod;}
ll dp[N][N];
int main()
{
     ios;
     ll n,k,x,y,ans=0;
     cin>>n>>k;
     for(int i=0;i<n-1;i++) cin>>x>>y;
     dp[0][0]=1;
     for(ll i=1;i<=n;i++)
     {
         for(ll j=1;j<=min(k,i);j++)
         {
             dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]*(k-(j-1)%mod))%mod;
         }
     }
     for(ll i=1;i<=k;i++) ans=(ans+dp[n][i])%mod;
     cout<<ans<<endl;
     return 0;
}
lpt的小屋 文章被收录于专栏

我想要一份甜甜的爱情

全部评论
%%%
2 回复 分享
发布于 2020-04-06 19:14
看了多篇题解,就看懂您的了,本来连题目意思都不懂的,看了您的立马理解了。 %%%%~~~
点赞 回复 分享
发布于 2021-02-21 18:15

相关推荐

02-09 16:14
武汉大学 Java
1.&nbsp;问一下本科经历2.&nbsp;介绍一下你第一个项目3.&nbsp;DDD分层架构比传统的MVC有哪些好处?4.&nbsp;你设计的业务分配的算法介绍一下?5.&nbsp;算法有哪些优化思路?6.&nbsp;动态标签列设计怎么思考的?7.&nbsp;数据量有多大?8.&nbsp;数据量很大的话,数据存储怎么优化?9.&nbsp;如何保证缓存和数据库之间的数据一致性?10.&nbsp;相对于你这个项目用哪种方案?11.&nbsp;项目中遇到的最大的困难是什么?12.&nbsp;介绍一下第二个项目13.&nbsp;模型分析diff的上下文怎么考虑?14.&nbsp;如果diff的关联的上下文很长超过token,你会怎么办?15.&nbsp;你想的这种方案,最后输入给模型的prompt是什么?16.&nbsp;对于大模型的其他组件如RAG和skills有了解吗?17.&nbsp;那你有想过把代码拆分成一些知识库放在rag里面吗?18.&nbsp;有对比过其他模型的分析效果吗?19.&nbsp;golang有了解吗?20.&nbsp;HashMap的底层结构21.&nbsp;为什么要用红黑树?22.&nbsp;红黑树增删的时间复杂度?23.&nbsp;MySQL事务隔离级别24.&nbsp;MVCC实现原理25.&nbsp;手撕算法:lc402&nbsp;移掉k位数字&nbsp;-&gt;&nbsp;没想到单调栈,暴力枚举了QAQ反问面试官之后,感觉我的缺点主要在于项目太过于玩具了,对于高并发什么的思考处于比较浅的地步,还有就是code-review对于call&nbsp;graph还有一些成熟的方案不怎么了解过,相当于纯demo,面过几场才知道QAQ,估计是没啥希望了,继续沉淀了噶人们
查看25道真题和解析
点赞 评论 收藏
分享
评论
10
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务