这道题的状态转移方程是dp[i]=dp[i]+dp[i-cost];由小到大进行递推,金额为i的组成方案,由未加入面值为cost金额为i的方案数和已加入面值为cost金额为i-cost的方案数组成,打表实现。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=30000,MAX=30100/5; //所给的金额都扩大20倍
long long dp[N]; //会超过int范围
int coins[11]= {1,2,4,10,20,40,100,200,400,1000,2000};
void Compelte_Pack(int cost)
{
for(int i=cost; i<=MAX; i++)
{
dp[i]+=dp[i-cost];
//金额为i的组成方案由原来未加入面值为cost的方案和减去当前面值的金额所对应方案相加
// cout<<"金额为"<<i<<" 组成方案有"<<dp[i]<<endl;
// if(i%10==0&&cost>1)
// getchar();
}
// getchar();
}
int main()
{
double n;
memset(dp,0,sizeof(dp)); //初始化为0,表示0元之外的其他金额没有合理的组成方案
dp[0]=1; //为0元时有一种方案
for(int i=0; i<11; i++)
{
Compelte_Pack(coins[i]); //将所有面值的都遍历一遍
}
while(scanf("%lf",&n)!=EOF&&n!=0)
{
int ans,temp=(int)(n*20+0.5);
printf("%6.2lf%17lld\n",n,dp[temp]);
}
return 0;
}