HDU 1284 钱币兑换问题
思路:此题是基础的完全背包问题。只有3个硬币,范围是32768,可以一个一个枚举硬币,如果只放价值为1的硬币,从d[1]递推到d[n];如果再加上价值为2的硬币,那么就从d[2]递推到d[n];在加上价值为3的硬币,就从d[3]递推到d[n].递推公式是d[j] = d[j] + d[ j-w[i] ]; d[j]表示j有几种只用1,2, 3这三个数字的拆分方法, w[i] 就是硬币的价值。
可以先打好表,然后直接求解
注意:和楼梯问题有区别,楼梯先上2阶再上1阶与先上1阶再上2阶,是两种。钱分为1分+2分,是一种.
#include<iostream>
#include<string.h>
using namespace std;
int dp[33000];
int w[3]={1,2,3};
void f()
{
int i,j;
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(i = 0; i < 3; i++) //i=0,只用1分硬币;i=1,只用1分和2分硬币;i=2,用1.2.3分硬币;
for(j = w[i]; j <= 33000; j++)
{
dp[j] = dp[j]+dp[j-w[i]];
}
}
int main()
{
int N;
f();
while(cin>>N)
{
cout<<dp[N]<<endl;
}
return 0;
}
i=0 w[i]=1 | j=1 | dp[1]=dp[1]+dp[1-1]=1 | 1 |
j=2 | dp[2]=dp[2]+dp[2-1]=1 | 11 | |
j=3 | dp[3]=dp[3]+dp[3-1]=1 | 111 | |
j=4 | dp[4]=dp[4]+dp[4-1]=1 | 1111 | |
j=5 | dp[5]=dp[5]+dp[5-1]=1 | 11111 | |
j=6 | dp[6]=dp[6]+dp[6-1]=1 | 111111 |
i=1 w[i]=2 | j=2 | dp[2]=dp[2]+dp[2-2]=2 | 11,2 |
j=3 | dp[3]=dp[3]+dp[3-2]=2 | 111,12 | |
j=4 | dp[4]=dp[4]+dp[4-2]=3 | 1111,112,22 | |
j=5 | dp[5]=dp[5]+dp[5-2]=3 | 11111,1112,122 | |
j=6 | dp[6]=dp[6]+dp[6-2]=4 | 111111,11112,1122,222 | |
i=2 w[i]=3 | j=3 | dp[3]=dp[3]+dp[3-3]=3 | 111,12,3 |
j=4 | dp[4]=dp[4]+dp[4-3]=4 | 1111,112,22,13 | |
j=5 | dp[5]=dp[5]+dp[5-3]=5 | 11111,1112,122,113,23 | |
j=6 | dp[6]=dp[6]+dp[6-3]=7 | 111111,11112,1122,222,1113,123,33 | |