0
点赞
收藏
分享

微信扫一扫

动态规划 01背包问题

hwwjian 2023-02-07 阅读 102


01背包问题

题目要求:

有N件物品和一个容量为V的背包。第i件物品的费用是c,价值是w。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

算法分析:

n  若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题:

n  如果不放第i件物品,则转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];

n  如果放第i件物品,则转化为“前i-物品放入剩下的容量为v-c[i]的背包中”,最大价值就是f[i-1][v-c[i]]+w[i]。

n  所以子问题解决方式 f[j]=max{f[j],f[v-c[i]]+w[i]};

实现细节:

空间优化:

fori=1..N

    for v=V..0

        f[v]=max{f[v],f[v-c[i]]+w[i]}; 

初始化细节:

若要求恰好装满背包,初始化时除了f[0]为0其它f[1..V]均设为-∞

若没有要求必须把背包装满,初始化时将f[0..V]全部设为0

 

代码实现:

 

#include<bits/stdc++.h>
using namespace std;
struct goods
{
int c,w; //c为价钱,w为价值
}goods[10000];
int main()
{
int n,v,i,j;
int f[1000];
cin>>n>>v;
for(i=0;i<=v;i++) //背包不要求装满
f[i]=0;
for(i=0;i<n;i++)
cin>>goods[i].c>>goods[i].w;
for(i=0;i<n;i++)
{
for(j=v;j>goods[i].c;j--)
if(f[j]<f[j-goods[i].c]+goods[i].w) //子问题重要条件
f[j]=f[j-goods[i].c]+goods[i].w;

}
cout<<f[v]<<endl;
return 0;
}


举报

相关推荐

0 条评论