01 背包 变形之转移价值

来源:互联网 发布:mac怎么加密文件夹 编辑:程序博客网 时间:2024/06/05 18:06

今天看算法导论dp。

这样的一道题 叙述和01背包一样

有n个重量和价值分别为wi vi的物品。 从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值。

注意限制条件

1<=n<=100

1<=wi<=1e7

1<=vi<=100

1<=W<=1e9


如果还是按照之前的 用价值转移的话

会发现这个算法会T

因为那个的复杂度是 O(nW)

所以这次的

dp[i+1][j]

是前i个物品中价值为j时的最小重量值

不存在时就是一个重量就是INF 初始化的时候用的 之后会提到

我在这里用的2e9

其实只要比1e9大就行

还有就是初始化 dp[0][0]=0 dp[0][j]=INF

这并不是说 前0个物品挑选价值为j的 最小重量是INF 而是相当于用这个INF 代表这种情况不存在

可以想一想为什么 dp[ 0][ 0] 为什么不是INF

下面是我的代码 大家可以看一看 不懂的可以互相交流 觉得写得不好的也可以提一提意见哈~~

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int maxn=100,maxv=100;int maxw,n;int dp[maxn+5][maxn*maxv+5];int w[maxn],v[maxn];const int INF=2000000000;void init(){    for(int j=0;j<maxn*maxv;j++)        dp[0][j]=INF;}void solve(){    for(int i=0;i<n;i++)        for(int j=0;j<=n*maxv;j++)        {            if(j<v[i])                dp[i+1][j]=dp[i][j];            else                dp[i+1][j]=min(dp[i][j],dp[i][j-v[i]]+w[i]);        }    int ans=0;    for(int i=0;i<=n*maxv;i++)    if(dp[n][i]<=maxw) ans=i;    printf("%d\n",ans);}int main(){    scanf("%d%d",&n,&maxw);    init();    dp[0][0]=0;    for(int i=0;i<n;i++)    {        scanf("%d%d",&w[i],&v[i]);    }    solve();    return 0;}


0 0
原创粉丝点击