题解 AT4525 【Knapsack 1】

01背包板子题

其实就是背包问题。

一,顺推

1,状态定义

我们不妨设 $dp[i][j]$ 表示取完第i个物品后,背包装了重量j的物品时的最大价值。因而答案为 $dp[n][w]$。

2,状态转移方程

边界条件:

- $i <= 0 时 dp[i][j] = 0$

对于第i个物品,可以选择选或不选

选:$dp[i][j] = dp[i-1][j-w[i]] + v[i]$

不选时:$dp[i][j] = dp[i-1][j]$

再比较两种选择取个max值。

3,代码

自己写吧。。。

二,倒推

dp既可以顺推,也可以倒推。

1,状态定义

我们不妨设 $dp[i][j]$ 表示取完第i个物品后,背包装了重量j的物品时的最大价值。由于是倒推,从最后一个物品开始,往前推,因而答案为 $dp[1][w]$。

2,状态转移方程

边界条件:

- $i <= 0 时 dp[i][j] = 0$

对于第i个物品,可以选择选或不选

选:$dp[i][j] = dp[i+1][j-w[i]] + v[i]$

不选时:$dp[i][j] = dp[i+1][j]$

再比较两种选择取个max值。

3,代码

#include<iostream>
using namespace std;
int vi[200],w[100000+10];
long long dp[200][100000+1];
int main(){
    int n,v;
    cin>>n>>v;
    for(int i = 1; i <= n; i++){
        cin>>vi[i]>>w[i];
    }
    for(int i = n; i >= 1; i--){
        for(int j = 1; j <= v; j++){
            if(j < vi[i]){
                dp[i][j] = dp[i+1][j];
            } 
            else{
                dp[i][j] =max(dp[i+1][j],dp[i+1][j-vi[i]] + w[i]);
            }
        }
    }
    cout<<dp[1][v];
    return 0;
} 

看懂了吗?希望对您有帮助。

posted @ 2021-01-26 18:46  WRuperD  阅读(1)  评论(0编辑  收藏  举报  来源

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

这是一条自定义内容

这是一条自定义内容