01背包问题

原题:

在这里插入图片描述

题目分析:具有重叠子问题和最优解结构,所以采取动态规划:

状态:

dp[i][j]表示在1 ~ i 件物品中,j的体积所得到的最优解(最大的价值);

初始化:

在只有一件物品的时候:
1> 如果该物品的体积小于等于当前给的定体积时候,就选中该物品dp[1][j] = w[j];

 else if (v[i] > j)dp[i][j] = dp[i - 1][j];

2> 如果该物品的体积大于当前给定的体积的时候,就不选该物品dp[1][j] = 0;
如果当前物体的体积(v[i])于当前给定的体积(j)的时候:
一定不选这个物品:dp[i][j] = dp[i - 1][j];

  if (i == 1) { // 一件物品
                if (v[i] <= j)dp[i][j] = w[i];
                else dp[i][j] = 0;
            }
         

状态转移方程:

dp[i][j] = max(dp[i -1][j],dp[i - 1][j - v[i]] + w[i])
o1背包问题主要关注物品的选与不选,其中:
dp[i - 1][j]:表示不选地i件物品,在j的体积下,在前i- 1件物品中选择;
dp[i - 1[j - v[i]] + w[i]:表示选择第i件物品,在去除i 所占的体积后(j - v[i]),在 i- 1件物品中选择;
max:在选与不选中选择价值最大的哪一种选择作为dp[i][j]的最优解;

最优解

**dp[N][V]**在1 ~ N的物品中,给定体积为V时可以选择的最大价值;

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
int v[1000000];
int w[1000000];
int dp[10000][10000]; // 状态
int main() {
    int N, V;
    cin >> N >> V;
    for (int i = 1; i <= N; i++) {
        
            cin >> v[i] >> w[i];
    
    }
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= V; j++) {
            if (i == 1) { //初始化
                if (v[i] <= j)dp[i][j] = w[i]; // 选择当前的一个物品
                else dp[i][j] = 0; // 不选择当前的一个物品
            }
            else if (v[i] > j)dp[i][j] = dp[i - 1][j];// 当前的物品体积大于当前给定的体积,不选择
            else {
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
               // 状态转移方程:选择该物品和不选择该物品相比较,选择价值最大的一个作为dp[i][j]
            }
           
        } 
    }
    
    cout << dp[N][V] << endl; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值