背包的硬币问题
在模模糊糊地看了完全背包后刷的几道水题,参考过网上的题解。
首先是 hdu 1028:http://acm.hdu.edu.cn/showproblem.php?pid=1028
这道题就是说整数划分,类似于完全背包,母函数暂时还不会,学了再回来补充,用完全背包优化后的版本:
1 #include<cstdio> 2 #include<cstring> 3 int f[123]= {1}; 4 5 int main(){ 6 for(int i=1 ;i<=120; ++i) 7 for(int j=i; j<=120; ++j) 8 f[j]+= f[j-i]; 9 int n; 10 while(~scanf("%d",&n)) 11 printf("%d\n",f[n]); 12 return 0; 13 }
然后是 hdu 1398: http://acm.hdu.edu.cn/showproblem.php?pid=1398
这道题只是变了一下而已,硬币值是平方数,不用数组来存,直接搞即可:
1 #include<cstdio> 2 int f[302]= {1}; 3 4 int main(){ 5 for(int i=1 ;i<=17; ++i) 6 for(int j=i*i; j<=300; ++j) 7 f[j]+= f[j-i*i]; 8 int n; 9 while(~scanf("%d",&n),n) 10 printf("%d\n",f[n]); 11 return 0; 12 }
接下来是 hdu 2069: http://acm.hdu.edu.cn/showproblem.php?pid=2069
这道稍微复杂一点点,因为多了个限制条件,硬币数不能超过100,参考别人的博客后,加多一维状态,来记录所用硬币的数量,然后结果要从1到100的硬币数量进行累加:
1 #include<cstdio> 2 const int coin[5]= {1,5,10,25,50}; 3 int f[108][260], ans[260]= {1}; 4 5 void init(){ 6 f[0][0]= 1; 7 for(int i=0; i<5; ++i) 8 for(int num=1; num<=100; ++num) 9 for(int j=coin[i]; j<=250; ++j) 10 f[num][j]+= f[num-1][j-coin[i]]; 11 for(int i=1; i<=250; ++i) 12 for(int num=1; num<=100; ++num) 13 ans[i]+= f[num][i]; 14 } 15 16 int main(){ 17 init(); 18 int n; 19 while(~scanf("%d",&n)) 20 printf("%d\n",ans[n]); 21 return 0; 22 }
感谢 http://www.cnblogs.com/qiufeihai/archive/2012/09/11/2680840.html 博客的指导!
背包问题,不断进取中~