12.12打卡

01背包问题的理解...

题目链接:22背包专题 [Cloned] - Virtual Judge (csgrandeur.cn)

一开始有几个问题导致没有很明白...现在基本上可以理解了

首先就是对于mjz[i][j](max价值)数组的理解。是对于前i个物品有j个空间时拿的最大价值是多少。

然后就是状态转移方程:mjz[i][j]=max(mjz[i-1][j],mjz[i-1][j-w[i]]+jz[i]);

这个一开始有一点小问题就是为什么要取最大值,因为在拿取第i个物品的时候就要腾出来第i个物品的空间,而在腾出来这些物品的时候可能会丢掉一些物品,然后就要判断是丢掉这些物品然后加上第i个物品价值大还是不带上第i个物品的价值大..

#include<iostream>
#include<cmath>
#include<cstring>

using namespace std;
int mjz[105][10005];
int w[105],jz[105];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
       cin>>w[i]>>jz[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(j<w[i]) mjz[i][j]=mjz[i-1][j];
            else {
                mjz[i][j]=max(mjz[i-1][j],mjz[i-1][j-w[i]]+jz[i]);
            }
        }
    }
    cout<<mjz[n][m];
}

然后就是对01背包的优化..

在动态转移的时候其实就只用到了两行一维数组,那么就可以变成一维数组,分为原来和更新后的大小。就是和原来自己比较和带上i个物品比较...

那么状态转移方程就是:mjz[j]=max(mjz[j-w[i]]+jz[i],mjz[j]);

在一维的情况下注意j循环要从后开始,因为如果要从前开始的那么就会修改原来mjz[j-w[i]]的值会导致不是上一个状态的价值,而如果从后开始往前判断,mjz[j-w[i]]就是原状态下的价值。

优化代码:

#include<iostream>
#include<cmath>
#include<cstring>

using namespace std;
int mjz[10005];
int w[105],jz[105];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
       cin>>w[i]>>jz[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=m;j>=w[i];j--){
            mjz[j]=max(mjz[j-w[i]]+jz[i],mjz[j]);
        }
    }
    cout<<mjz[m];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值