您的位置:首页 > 其它

NYOJ 49 开心的小明 (dp问题之01背包问题)

2012-08-14 08:36 330 查看
地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=49

思路:01背包问题

考虑使用dp问题 求解,定义一个递归式 opt[i][v] 表示前i个物品,在背包容量大小为v的情况下,最大的装载量。
opt[i][v] = max(opt[i-1][v] , opt[i-1][v-c[i]] + w[i]) //w[i]是容量为c[i]时的装载量
解释如下:
opt[i-1][v] 表示第i件物品不装入背包中,而opt[i-1][v-c[i]] + w[i] 表示第i件物品装入背包中。

#include<iostream>
#include<cstring>
using namespace std;
int f[30001];
int main()
{
int i,T,n,m,v,w;
cin>>T;
while(T--)
{
cin>>n>>m;     //输入总钱数和物品最大个数
memset(f,0,sizeof(f));
while(m--)
{
cin>>v>>w;   //输入每个物品的价格和权值
for(i=n;i>=v;i--)
f[i]=max(f[i],f[i-v]+w*v);  //这点是关键,f[i]表示当前容量为i时乘过权值的价格,f[i-v]+w*v表示在i-v这个容量时加上w*v与此时的f[i]容量相比较,取最大值,即最优解,转化为01背包问题去思考,
}
cout<<f
<<endl;
}
return 0;
}


别人的思路:

分析:01背包;d[i][j]表示在前 i 个物品中选择一些物品放入容量为 j 的背包中 第 i 个物体有放和不放两种情况

不放:就相当于在前 i-1 个物品中选择 即 d[i-1][j];

放:就是前 i-1 个物品只有 j-v 的容量让放 即 d[i-1][j-v]+w;

综合两种情况的最优是 d[i][j]=max{d[i-1][j] , d[i-1][j-v]+w};

空间优化如下:

d[i]表示容量为 i 的最优值,a[]表示物品的重量,b[]表示对应的价值量;

d[i]=max(d[i] , d[i-a[i]] + a[i]*b[i]);

#include<iostream>
#include<cstring>
#define M 30010
#define N 30
using namespace std;

int d[M],a
,b
;

int max(int x,int y)
{
return x>y?x:y;
}

int main()
{
int test,m,n,i,j;
cin>>test;
while(test--)
{
cin>>m>>n;
for(i=1;i<=n;i++) cin>>a[i]>>b[i];
memset(d,0,sizeof(d));
for(i=1;i<=n;i++)
{
for(j=m;j>=a[i];j--)
{
d[j]=max(d[j],d[j-a[i]]+a[i]*b[i]);
}
}
cout<<d[m]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: