HDU 1114 Piggy-Bank (dp问题之完全背包问题)

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1114

思路:动态规划之完全背包问题

题目分析:给出了钱罐开始的重量e和装满后的重量f,然后给你n种硬币,每个价值为p,重量为w,求出最小的价值使钱罐的重量恰好为w

如果不存在 输出This is impossible.

状态转移方程:f[v]=min{f[v],f[v-w[i]]+p[i]}

注意:一道简单的完全背包题(于0-1背包就是第二个for循环倒过来就行了)
,要求做的仅仅是求最小值,而不是最大值,那么只要对初始化进
行一些改变就可以了。把f[0]赋值为0,其他赋值为无穷大。

这个题目的意思是有一只存钱的小猪灌,告诉你它空着的时候的重量,以及满着的时候的重量。然后有一些钱币,每种钱币都有自己的价值和重量。每种钱币可以使用任意的次数。现在题目的要求就是要你把这个储钱罐装满,但是里面装的钱币的价值要是最少的。这就和我们以前做过的完全背包问题相反了。怎么做呢?很简单。就是状态转移方程f[j]在赋初值的时候全部赋成正无穷大,表示在j背包容量下什么都不装所能达到的最小价值为正无穷,也就是一个无效的背包。但是f[0]要赋作0,因为在0背包容量下你什么都不能放进去,则最小的当然是0,是一个有效的状态。而整个背包的总容量就是用满重量的容量减去空的时候的容量。再根据完全背包的算法求出装满情况下最少的价值。如果最后f[V]为无效状态的话,则代表,这个背包根本就不能装满,那说明在所给的条件下是无法满足要求的,输出“This is impossible.”。如果不是,则说明存在最小值,则输出。完全背包思想详见:http://love-oriented.com/pack/P02.html

代码如下:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define INF 0xfffffff
 4 int dp[10010];
 5 int min(int x,int y)
 6 {
 7     return x>y?y:x;
 8 }
 9 int main()
10 {
11     int t,e,f,n,m,p,w,i,j;
12     scanf("%d",&t);
13     while(t--)
14     {
15         scanf("%d%d",&e,&f);
16         m=f-e;
17         for(i=1;i<=m;i++)
18         dp[i]=INF; dp[0]=0;     //这点的初始化表示不太懂,有待进一步的研究。。。
19         scanf("%d",&n);
20         for(i=0;i<n;i++)
21         {
22             scanf("%d%d",&p,&w);
23             for(j=w;j<=m;j++)  //与01背包相比倒过来 
24             {
25                 dp[j]=min(dp[j],dp[j-w]+p);
26             }
27         }
28         if(dp[m]==INF)
29            printf("This is impossible.\n");
30         else
31            printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);
32     }
33     system("pause");
34     return 0;
35 }    

posted on 2012-08-22 16:15  mycapple  阅读(1008)  评论(0编辑  收藏  举报

导航