完全背包
题目大意是有一个地方习惯用1到17的平方数作为货币,然后给你一个数额,求出有多少种组合来支付这个数额。
比如说数额为10,那么一共有4种组合。分别是:
10张1元的,1张4元的和6张1元的,2张4元的和2张1元的,1张9元的和1张1元的。
这题我是2A的,第一次做没有用完全背包,AC代码是
#include <stdio.h> #include <string.h> #define N 310 int main() { int n,i,j,k; int c1[N],c2[N]; while(scanf("%d",&n),n) { for(i=0;i<=n;i++) { c1[i]=1; c2[i]=0; } for(i=2;i*i<=n;i++) { for(j=0;j<=n;j++) { for(k=0;k+j<=n;k=k+i*i) { c2[k+j]=c2[k+j]+c1[j]; } } for(j=0;j<=n;j++) { c1[j]=c2[j]; c2[j]=0; } } printf("%d\n",c1[n]); } return 0; }
第二次是用完全背包做的。
首先先存好一个所有钱的数组,即{0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289}
然后状态方程是
if(i > step[index]) { dp[i] = dp[i-step[index]]+dp[i]; }
AC代码如下:
#include <stdio.h> #include <string.h> int step[18] = {0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289}; int main() { int index = 1,i,money; int dp[305]; while(scanf("%d",&money),money) { memset(dp,0,sizeof(dp)); dp[1] = 1; for(index = 1; index < 18; index++) { for(i = 1; i <= money+1; i++) { if(i > step[index]) { dp[i] = dp[i-step[index]]+dp[i]; } } } printf("%d\n",dp[money+1]); } return 0; }