背包的硬币问题

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

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

  背包问题,不断进取中~

 

你可能感兴趣的:(问题)