hdu 5185 dp(完全背包)

时间:2023-03-10 02:20:41
hdu 5185 dp(完全背包)

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 种,即初始化。

 #include<stdio.h>
#include<string.h>
#include<math.h>
#define ll long long
#define max(a,b) a>b?a:b int dp[][]; int main(){
int T;
while(scanf("%d",&T)!=EOF){
for(int q=;q<=T;q++){
int n,mod,ans=;
scanf("%d%d",&n,&mod);
memset(dp,,sizeof(dp));
int m=(sqrt(8.0*n+)-)/;
int i,j;
// printf("%d\n",m);
dp[][]=;
for(i=;i<=m;i++){
for(j=;j<=n;j++){
if(i>j)dp[i][j]=;
else dp[i][j]=(dp[i-][j-i]+dp[i][j-i])%mod;
if(j==n)ans=(ans+dp[i][j])%mod;
}
}/*
for(i=0;i<=m;i++){
for(j=0;j<=n;j++){
printf("%3d",dp[i][j]);
}
printf("\n");
}*/
printf("Case #%d: %d\n",q,ans);
}
}
return ;
}