背包:01bag(dp)

概念

01背包,就是要么装进去,或者不装入bag,使得背包的容量不超过的前提下,产生的经济最大

dp:

通过动态规划dp实现将大问题分解多个子问题

dp表示经济价值
w[i] 表示第i个物品的经济价值

v[i]表示第i个物品的体积

\[dp_{ij} = max(dp_{i-1j},dp_{i-1,j-v[i]}+w[i]) \]

如上图横坐标表示的是背包的当前容量,纵坐标表示是各个物品

代码实现

//题目https://www.acwing.com/problem/content/description/2/
#include<iostream>
#include<cmath>
using namespace std;
const int N=10010;
int v[N],w[N];//v[i]体积w[i]money
int dp[N][N];
int n,m;
int main(){
    cin>>n>>m;//输入物品个数和bag容量
    for(int i = 1;i<=n;i++){
        cin>>v[i]>>w[i];//各物品
    }
    for(int i = 1;i<=n;i++){
        for(int j = 0;j<=m;j++){
            dp[i][j] = dp[i-1][j];//这步是灵魂
            if(j>=v[i]){
                dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);//对比上图
            }
        }
    }
    cout<<dp[n][m];
    
}

dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
j-w[i]是看其他的bag效益最大,j是从0->m,所有一定会得到前面的一个值

当dp[i-1][j] = dp[i][j],说明当前没有被选择,否则测试dp[i-1][j-w[i]];

ans = m;//容量
for(int i =n;i>=1;i--){
        if(dp[i-1][ans] != dp[i][ans]){
            ans-=w[i];
            cout<<i<<" ";
        }
    }//倒叙

参考

01dp
acwing

posted @ 2022-11-10 14:55  壹剑霜寒十四州  阅读(25)  评论(0编辑  收藏  举报