您的位置:首页 > 其它

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

2012-08-22 16:15 453 查看
地址: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

代码如下:

#include<stdio.h>
#include<stdlib.h>
#define INF 0xfffffff
int dp[10010];
int min(int x,int y)
{
return x>y?y:x;
}
int main()
{
int t,e,f,n,m,p,w,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&e,&f);
m=f-e;
for(i=1;i<=m;i++)
dp[i]=INF; dp[0]=0;     //这点的初始化表示不太懂,有待进一步的研究。。。
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&p,&w);
for(j=w;j<=m;j++)  //与01背包相比倒过来
{
dp[j]=min(dp[j],dp[j-w]+p);
}
}
if(dp[m]==INF)
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: