Petya and Coloring
[cpp]/*
题目简化为求i个块砖中从k种颜色中选j种,每种颜色至少涂1次的方案数
程序1
dp[i][j]表示前i块砖在k种不同的颜色中用了j种颜色的方案数
dp[i][j]=(dp[i][j]+dp[i-1][j-1]*(k-j+1))%mod;
dp[i][j]=(dp[i][j]+dp[i-1][j]*j)%mod;
程序2
dp[i][j]表示前i块砖用j种颜色的方案数,不考虑具体颜色.只看重种数
相当于是一种模式
dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod;
dp[i][j]=(dp[i][j]+dp[i-1][j]*j)%mod;
(dp[i][j]*fac[j]%mod)*Cal(k,j)%mod(程序2的dp)=dp[i][j](程序1的dp)
*/
#include<stdio.h>
#include<string.h>
typedef __int64 lld;
const int mod=1000000007;
const int maxn=1005;
lld C[maxn][maxn];
lld dp[maxn][maxn];
lld fac[1000005];
int n,m,k;
void init(){
int i,j;
fac[0]=1;
for(i=1;i<1000005;i++)
fac[i]=(fac[i-1]*i)%mod;
}
lld Mul(lld a,lld b){
lld ret=1;
while(b){
if(b&1)ret=ret*a%mod;
b>>=1;
a=a*a%mod;
}
return ret;
}
lld Cal(int x,int y){
lld tmp=fac[x]*Mul(fac[x-y]*fac[y]%mod,mod-2)%mod;
return tmp;
}
int main(){
int i,j;
init();
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
if(k>=j-1)
dp[i][j]=(dp[i][j]+dp[i-1][j-1]*(k-j+1))%mod;
dp[i][j]=(dp[i][j]+dp[i-1][j]*j)%mod;
}
}
/*
for(i=1;i<=15;i++){
for(j=1;j<=i;j++){
printf("%I64d ",dp[i][j]);
}
puts("");
}*/
lld ans=0;
if(m==1){
printf("%I64d\n",Mul(k,n));
}else{
for(i=1;i<=n && i<=k;i++){//最左最右个有i
for(j=(m!=2);j<=i;j++)//中间m-2的部分用j种
if(k>=2*i-j){
lld tp=Cal(i,j)*Mul(j,n*(m-2))%mod;
lld tg=dp[n][i]*dp[n][i]%mod;
lld tf=Cal(k-i,i-j)*Mul(Cal(k,i),mod-2)%mod;
ans=(ans+((tp*tf%mod)*tg%mod))%mod;
}
}
printf("%I64d\n",ans);
}
}
return 0;
}
/*
#include<stdio.h>
#include<string.h>
typedef __int64 lld;
const int mod=1000000007;
const int maxn=1005;
lld C[maxn][maxn];
lld dp[maxn][maxn];
lld fac[1000005];
int n,m,k;
void init(){
int i,j;
fac[0]=1;
for(i=1;i<1000005;i++)
fac[i]=fac[i-1]*i%mod;
}
lld Mul(lld a,lld b){
lld ret=1;
while(b){
if(b&1)ret=ret*a%mod;
b>>=1;
a=a*a%mod;
}
return ret;
}
lld Cal(int x,int y){
lld tmp=fac[x]*Mul(fac[x-y]*fac[y]%mod,mod-2)%mod;
return tmp;
}
int main(){
int i,j;
init();
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod;
dp[i][j]=(dp[i][j]+dp[i-1][j]*j)%mod;
}
}
***************
for(i=1;i<=15;i++){
for(j=1;j<=i;j++){
if(k>=j)
printf("%I64d ",(dp[i][j]*fac[j]%mod)*Cal(k,j)%mod);
else
&nb
补充:软件开发 , C++ ,