您的位置:首页 > 理论基础 > 计算机网络

http://acm.hdu.edu.cn/showproblem.php?pid=1114&&完全背包

2012-03-20 11:13 253 查看
题意:硬币的数量不限制,让储蓄罐装满时得到的最少价值。

思路:先将完全背包转化成多重背包,再转化成0-1背包来解,不过这里要进行二进制优化,因为这里要保证储蓄罐要装满,所以需要先把容量为0时,价值赋为0,因为让求最小价值,因此需要把大于0的容量都赋为无穷大,如果让求的是装满时的最大价值则要把大于0的容量都赋为无穷小。。。

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 10000;
int dp[10001];
int w[350005];
int v[350005];
int main()
{
int t;
cin>>t;
while(t--)
{
int p,q;
cin>>p>>q;
p=q-p;
for(int i=0;i<10001;++i)
dp[i]=0xfffff;
dp[0]=0;
int n;
cin>>n;
int tot=0;
for(int i=0;i!=n;++i)
{
int a,b;
cin>>a>>b;
int k=p/b;
int t=1;
while(2*t<k+1)
{
w[tot]=t*b;
v[tot++]=t*a;
t=2*t;
}
w[tot]=(k+1-t)*b;
v[tot++]=(k+1-t)*a;
}
for(int i=0;i<tot;++i)
{
if(w[i]>p) continue;
for(int j=p;j>=w[i];--j)
dp[j]=min(dp[j-w[i]]+v[i],dp[j]);
}
if(dp[p]<0xfffff) cout<<"The minimum amount of money in the piggy-bank is "<<dp[p]<<"."<<endl;
else cout<<"This is impossible."<<endl;
}return 0;
}

完全背包:

#include<iostream>
#include<string.h>
#include<algorithm>
#define N 10001
using namespace std;
int dp
;
int w[501],v[501];
int main()
{
int t;
cin>>t;
while(t--)
{
int p,q;
cin>>p>>q;
p=q-p;
int n;
cin>>n;
for(int i=0;i<N;++i)
dp[i]=0xfffff;
dp[0]=0;
for(int i=0;i!=n;++i)
cin>>v[i]>>w[i];
for(int i=0;i<n;++i)
{
if(w[i]>p) continue;
for(int j=w[i];j<=p;++j)
{
dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
}
}

if(dp[p]<0xfffff) cout<<"The minimum amount of money in the piggy-bank is "<<dp[p]<<"."<<endl;
else cout<<"This is impossible."<<endl;
}return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化