标签:
BC # 32 1004
题意:要求 n 个数和为 n ,而且后一个数等于前一个数或者等于前一个数加 1 ,问有多少种组合。
其实是一道很水的完全背包,但是没有了 dp 的分类我几乎没有往这边细想,又是放在第四题,因此完全没有想出来。
其实并不难,dp [ i ] [ j ] 表示当前放入 i ,总和是 j 的种类数
dp [ i ] [ j ] = dp [ i - 1 ] [ j - i ] + dp [ i ] [ j - i ] ;即上一个放的是 i 或 i - 1 ;
dp [ 0 ] [ 0 ] = 1 表示不放数字和为 0 种类数为 1 种,即初始化。
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #define ll long long 5 #define max(a,b) a>b?a:b 6 7 int dp[320][50005]; 8 9 int main(){ 10 int T; 11 while(scanf("%d",&T)!=EOF){ 12 for(int q=1;q<=T;q++){ 13 int n,mod,ans=0; 14 scanf("%d%d",&n,&mod); 15 memset(dp,0,sizeof(dp)); 16 int m=(sqrt(8.0*n+1)-1)/2; 17 int i,j; 18 // printf("%d\n",m); 19 dp[0][0]=1; 20 for(i=1;i<=m;i++){ 21 for(j=0;j<=n;j++){ 22 if(i>j)dp[i][j]=0; 23 else dp[i][j]=(dp[i-1][j-i]+dp[i][j-i])%mod; 24 if(j==n)ans=(ans+dp[i][j])%mod; 25 } 26 }/* 27 for(i=0;i<=m;i++){ 28 for(j=0;j<=n;j++){ 29 printf("%3d",dp[i][j]); 30 } 31 printf("\n"); 32 }*/ 33 printf("Case #%d: %d\n",q,ans); 34 } 35 } 36 return 0; 37 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4331292.html