DPL_1_B:0-1 Knapsack Problem [动态规划] 0-1背包问题

题目链接

题目给出n个物品,物品的价值vi,质量为wi,现在要求出承重为w袋子能装下多少价值的物品,求出总价值;

考虑对于每个物品都有装和不装两个选择,称之为0-1背包问题;

d p [ i ] [ j ] 来表示,只用第1-i个物品,承重不超过j的情况下,能获得的最大价值;

可以获得递推关系:

d p [ i ] [ j ] = m a x ( d p [ i 1 ] [ j ] , d p [ i 1 ] [ j w e i g h t [ i ] ] + v a l u e [ i ] )

利用这一递推关系,遍历得出dp数组:

for(i from 1 to n)
    for(j from 1 to w)
        if(j<weight[i]) dp[i][j]=dp[i-1][j]
        else dp[i][j]=max( dp[i-1][j] , dp[i-1][j-weight[i]]+value[i] ) 

最后 d p [ n ] [ w ] 就是所求的,在n个物品,承重w的袋子里装下的物品的最大价值;
全部代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=106;
const int maxw=1e4+6;
const int INF=0x7fffffff;

class node{
public:
    int value,weight;
    node(int value=0,int weight=0):value(value),weight(weight){}    
}a[maxn];

int n,w;
int dp[maxn][maxw];

int main() {
    std::ios::sync_with_stdio(false);
    cin>>n>>w;
    int x,y;
    for(int i=1;i<=n;i++){
        cin>>x>>y;
        a[i]=node(x,y);
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=w;j++){
            if(j<a[i].weight) dp[i][j]=dp[i-1][j];
            else dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i].weight]+a[i].value);
        }
    }
    cout<<dp[n][w]<<endl;
    return 0;
}

错点:
1. 遍历的时候,不可以直接 d p [ i ] [ j ] = m a x ( d p [ i 1 ] [ j ] , d p [ i 1 ] [ j w e i g h t [ i ] ] + v a l u e [ i ] ) 因为 当第i个不选择的时候,还有可能选择前面其他的物品;不能for(int j=a[i].weight)开始;

猜你喜欢

转载自blog.csdn.net/qq_33982232/article/details/81592376