当前位置:编程学习 > C/C++ >>

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++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,