背包的硬币问题

  在模模糊糊地看了完全背包后刷的几道水题,参考过网上的题解。

首先是 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 博客的指导!

  背包问题,不断进取中~

 

posted @ 2014-12-04 14:31  Newdawn_ALM  阅读(164)  评论(0编辑  收藏  举报