标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 165 Accepted Submission(s): 64
官方题解:
1002 Harry And Magic Box dp题,我们一行一行的考虑。dp[i][j],表示前i行,都满足了每一行至少有一个宝石的条件,而只有j列满足了有宝石的条件的情况有多少种。枚举第i+1行放的宝石数k,这k个当中有t个是放在没有宝石的列上的,那么我们可以得到转移方程: dp[i+1][j+t]+=dp[i][j]*c[m-j][t]*c[j][k-t],其中c[x][y],意为在x个不同元素中无序地选出y个元素的所有组合的个数。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<map> 9 #include<set> 10 #include<string> 11 12 #define N 55 13 #define M 10 14 #define mod 1000000007 15 //#define p 10000007 16 #define mod2 1000000000 17 #define ll long long 18 #define LL long long 19 #define eps 1e-9 20 #define maxi(a,b) (a)>(b)? (a) : (b) 21 #define mini(a,b) (a)<(b)? (a) : (b) 22 23 using namespace std; 24 25 ll n,m; 26 ll dp[N][N]; 27 ll ans; 28 ll c[N][N]; 29 ll sum[N][N]; 30 31 void ini1() 32 { 33 memset(c,0,sizeof(c)); 34 memset(sum,0,sizeof(sum)); 35 int i,j; 36 for(i=0;i<=N-5;i++){ 37 c[i][0]=c[i][i]=1; 38 } 39 for(i=2;i<=N-5;i++){ 40 for(j=1;j<i;j++){ 41 c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; 42 } 43 } 44 //for(i=1;i<=M-5;i++){ 45 // for(j=0;j<=i;j++){ 46 // printf(" i=%d j=%d c=%I64d\n",i,j,c[i][j]); 47 // } 48 //} 49 for(i=1;i<=N-5;i++){ 50 sum[i][0]=1; 51 for(j=1;j<=i;j++){ 52 sum[i][j]=(sum[i][j-1]+c[i][j])%mod; 53 } 54 } 55 } 56 57 void ini() 58 { 59 memset(dp,0,sizeof(dp)); 60 ans=0; 61 dp[0][0]=1; 62 } 63 64 void solve() 65 { 66 int i,j,k,o; 67 i=1; 68 for(j=1;j<=m;j++){ 69 dp[i][j]=c[m][j]; 70 } 71 for(i=2;i<=n;i++){ 72 for(j=1;j<=m;j++){ 73 dp[i][j]=( dp[i-1][j]*(sum[j][j]-1) )%mod; 74 for(k=1;k<j;k++){ 75 o=j-k; 76 dp[i][j]=(dp[i][j]+( ( dp[i-1][k]*(sum[k][k]) ) %mod ) * (c[m-k][o]) )%mod; 77 } 78 } 79 } 80 } 81 82 void out() 83 { 84 //int i,j; 85 86 //for(i=1;i<=n;i++){ 87 // for(j=1;j<=m;j++){ 88 // printf(" i=%d j=%d dp=%I64d\n",i,j,dp[i][j]); 89 // } 90 // } 91 ans=(dp[n][m])%mod; 92 printf("%I64d\n",ans); 93 } 94 95 int main() 96 { 97 ini1(); 98 // freopen("data.in","r",stdin); 99 //freopen("data.out","w",stdout); 100 //scanf("%d",&T); 101 //for(int ccnt=1;ccnt<=T;ccnt++) 102 // while(T--) 103 while(scanf("%I64d%I64d",&n,&m)!=EOF) 104 { 105 ini(); 106 solve(); 107 out(); 108 } 109 110 return 0; 111 }
BestCoder Round #25 1002 Harry And Magic Box [dp]
标签:
原文地址:http://www.cnblogs.com/njczy2010/p/4205551.html