http://acm.hdu.edu.cn/showproblem.php?pid=4301
题意:
有一块n*2大小的巧克力,现在某人要将这巧克力分成k个部分,每个部分大小随意,问有多少种分法。
思路:
dp [ i ] [ j ] [ 0/1 ]表示到第 i 列时分成 j 块的方案数,0/1表示第 i 列的两格巧克力是否相连。
这样的话,分析到第 i 块时的情况如下:
①块数不变
dp[i][j][1] = dp[i][j][1] + dp[i-1][j][0]*2 dp[i][j][0] = dp[i-1][j][0]
②块数+1
dp[i][j][1] = dp[i-1][j-1][0] + dp[i-1][j-1][1] dp[i][j][0] = dp[i-1][j-1][0]*2 + dp[i-1][j-1][1]*2
③块数+2
dp[i][j][0] = dp[i-1][j-2][1] + dp[i-1][j-2][0]
最后加起来即可。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int mod = 100000007; 5 6 7 int n, k; 8 int dp[1005][2005][2]; 9 10 int main() 11 { 12 dp[1][1][1] = 1; 13 dp[1][1][0] = 0; 14 dp[1][2][1] = 0; 15 dp[1][2][0] = 1; 16 for(int i=2;i<=1000;i++) 17 { 18 for(int j=1;j<=2*i;j++) 19 { 20 dp[i][j][1] += dp[i-1][j][1] + dp[i-1][j][0]*2; 21 dp[i][j][1]%=mod; 22 dp[i][j][0] += dp[i-1][j][0]; 23 dp[i][j][0]%=mod; 24 dp[i][j][1] += dp[i-1][j-1][0] + dp[i-1][j-1][1]; 25 dp[i][j][1]%=mod; 26 dp[i][j][0] += dp[i-1][j-1][1]*2 + dp[i-1][j-1][0]*2; 27 dp[i][j][0]%=mod; 28 if(j>2) 29 { 30 dp[i][j][0] += dp[i-1][j-2][1] + dp[i-1][j-2][0]; 31 dp[i][j][0]%=mod; 32 } 33 } 34 } 35 int T; 36 scanf("%d",&T); 37 while(T--) 38 { 39 scanf("%d%d",&n,&k); 40 printf("%d ",(dp[n][k][0]+dp[n][k][1])%mod); 41 } 42 return 0; 43 }