钱币兑换问题 (完全背包)
代码:(完全背包)
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int dp[32775]; int main() { int i,j,n; memset(dp,0,sizeof(dp)); dp[0]=1; for(i=1;i<=3;i++) { for(j=i;j<=32775;j++)//j代表的是钱数,不能小于当前价值为i的硬币 { dp[j]+=dp[j-i];
//dp[i][j]=dp[i-1][j]+dp[i][j-i];//表示用前i种硬币构造j美分的总方法数 } } while(scanf("%d",&n)==1) { printf("%d\n",dp[n]); } return 0; }
其他解法详见:http://blog.sina.com.cn/s/blog_91e2390c01014b1u.html
假如3的个数为i,则剩余的需兑换的钱有n-3*i,剩余的对2来说,有可能有0,1,2...(n-3*i)/2;即有i个3的情况有 (n-3*i)/2+1个(2从0开始) ;
3和2的个数确定了,1的个数也确定;
#include<stdio.h> int main() { int n; while(~scanf("%d",&n)) { long long sum=0; for(int i=0 ; i<=n/3 ; i++)//枚举3的可能个数,有n/3种可能 sum+=(n-3*i)/2+1;//+1是因为,每一种换法可以直接全部换为1元硬币 printf("%lld\n",sum); } return 0; }