hdu 6143 Killer Names(组合计数)(DP)
来源:互联网 发布:海诺网络 编辑:程序博客网 时间:2024/05/18 12:30
题目链接:Killer Names
题意
要求构造若干名字,名字包括first name
last name
两部分,均需包含 n 个字符,已知有 m 种字符供选择,求最多有多少种不同的构造方法,使得 first name
和 last name
不含相同字符。
也就相当于m 种颜色需要为两段长度为 n 的格子染色,且这两段之间不能出现相同的颜色,问总共有多少种情况。
思路
设这两段分配的颜色数目分别为
而在每段内部,设
则有
此时第二段则用
因此最终的结果便是
代码:
#include<bits/stdc++.h>using namespace std;typedef long long LL;const LL mod=1e9+7;const int maxn=2e3+5;const int N=2e3;LL C[maxn][maxn],f[maxn];//f[]表示用i种颜色填n个格子的种数LL qmod(LL x,int n){ LL res=1; while(n) { if(n&1) res=res*x%mod; x=x*x%mod; n>>=1; } return res;}void init()//组合数{ for(int i=1; i<=N; ++i) { C[i][0]=C[i][i]=1; for(LL j=1; j<i; ++j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; }}void calc(int n){ f[1]=1; for(int i=2; i<=n; ++i) { LL tmp=0; for(int j=1; j<i; ++j) tmp=(tmp+C[i][j]*f[j]%mod)%mod; f[i]=(qmod(i,n)-tmp+mod)%mod; }}int main(){ init(); int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); calc(n); LL ans=0; for(int i=1; i<=n&&i<m; ++i) ans=(ans+(C[m][i]*f[i]%mod)*qmod(m-i,n)%mod)%mod; printf("%lld\n",ans); } return 0;}
也可以使用 Stirling 数
在题目中就是,将
即结果为
代码:
#include<bits/stdc++.h>using namespace std;typedef long long LL;const LL mod=1e9+7;const int maxn=2e3+5;const int N=2e3;LL C[maxn][maxn],S[maxn][maxn];//S[][]第二类斯特林数LL A[maxn];//阶乘LL qmod(LL x,int n){ LL res=1; while(n) { if(n&1) res=res*x%mod; x=x*x%mod; n>>=1; } return res;}void init(){ for(int i=1; i<=N; ++i) { C[i][0]=C[i][i]=1; for(int j=1; j<i; ++j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; } A[1]=1; for(int i=2; i<=N; ++i) A[i]=i*A[i-1]%mod; for(int i=1; i<=N; ++i) { S[i][0]=0,S[i][1]=1; for(int j=2; j<=i; ++j) S[i][j]=(j*S[i-1][j]%mod+S[i-1][j-1])%mod; }}int main(){ init(); int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); LL ans=0; for(int i=1; i<=n&&i<m; ++i) ans=(ans+((C[m][i]*A[i]%mod)*S[n][i]%mod)*qmod(m-i,n)%mod)%mod; printf("%lld\n",ans); } return 0;}
DP也可以做
则
代码:
#include<bits/stdc++.h>using namespace std;typedef long long LL;const LL mod=1e9+7;const int maxn=2e3+5;const int N=2e3;LL dp[maxn][maxn];LL qmod(LL x,int n){ LL res=1; while(n) { if(n&1) res=res*x%mod; x=x*x%mod; n>>=1; } return res;}int main(){ int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); dp[1][1]=m; for(int i=2; i<=n; ++i) for(int j=1; j<=i&&j<m; ++j) dp[i][j]=(dp[i-1][j-1]*(m-j+1)%mod+dp[i-1][j]*j%mod)%mod; LL ans=0; for(int i=1; i<m&&i<=n; ++i) ans=(ans+dp[n][i]*qmod(m-i,n)%mod)%mod; printf("%lld\n",ans); } return 0;}
阅读全文
1 0
- hdu 6143 Killer Names(组合计数)(DP)
- HDU 6143 Killer Names(dp 思维)
- HDU 6143 Killer Names(容斥+组合)
- hdu 6143 Killer Names (组合数,递推)
- Killer Names(hdu 6143)
- Killer Names(HDU 6143)
- HDU 6143 Killer Names(排列+容斥,dp)
- hdu 6143 Killer Names dp
- HDU 6143 Killer Names (容斥)
- HDU 6143 Killer Names(容斥)
- hdu 6143 Killer Names(第二类斯特林数)
- HDU 6143 Killer Names(dp+容斥)
- HDU 6143 Killer Names(组合数+第二类Stirling数)
- HDU 6143 Killer Names 组合数+(容斥/第二类Stirling数)
- HDU 6143 Killer Names
- hdu--6143--Killer Names
- hdu 6143 Killer Names
- hdu 6143 Killer Names
- Cordova开发环境搭建
- 科大讯飞手写识别
- 这是一篇用测试MetaAPI的测试内容2
- 树-堆结构练习——合并果子之哈夫曼树(优先队列)
- 膜法师【NOIP提高组模拟A组8.15】
- hdu 6143 Killer Names(组合计数)(DP)
- MyBatis:系列讲解
- 22、数据压缩-霍夫曼编码
- SpringMVC的在线人数统计监听器
- vuejs之路之--事件绑定
- 文本读写
- init
- JavaWeb学习之请求转发和重定向
- POJ题目分类