列表

详情


MT22. 双袋购物

描述

一条马路上有 n 个点,从左到右从 1 到 n 编号。小明一开始在马路的最左边,一直往右走,一直走到马路的最右边,一直往右走,一直走到马路的最右边,中途不允许回头,只能往右走。

每个点上都有一个物品,第 i 个点的物品体积为 vi,价值为 wi,(注意:先输入体积再输入价值)小明有两个袋子,一号袋子和二号袋子,一号袋子体积为 A ,二号袋子体积为 B 。
最开始小明使用一号袋子,经过一个点的时候,他可以选择把点上的物品放入袋子中,但是袋中物品的总体积不能超过袋子的体积,也可以选择不拿这个物品。
在整个过程中的任意一个时刻,小明可以选择把一号袋子收起来,接下来使用二号袋子,一旦小明收起了一号袋子,之后他再也不能使用一号袋子,接下来的物品只能决策是否放入二号袋子中,且袋中的物品的总体积不能超过袋子容量。特别的,小明可以在最开始(遇到 1 号点之前)就换袋子,这样他全程都使用二号袋子 ;他也可以一直使用一号袋子,到最后也不收。
小明最后获得的价值为两袋子中物品价值和,问在最优策略下的最大价值。

数据范围:

输入描述

输入第一行三个数 n , A , B。 接下里有 n 行,每行两个数 v_i , w_i 依次表示每个物品的体积和价值。

输出描述

输出一个数,最大价值

示例1

输入:

5 10 50
3 3
7 4
4 7
49 50
2 2

输出:

60

说明:

用一号袋子装1号和3号物品,之后收起一号袋子,用二号袋子装4号物品。

原站题解

C++ 解法, 执行用时: 4ms, 内存消耗: 456KB, 提交时间: 2021-09-11

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    int n,A,B,idx=0;
    cin>>n>>A>>B;
    vector<int> value(n);
    vector<int> weight(n);
    while(n--){
        cin>>weight[idx]>>value[idx];
        idx++;
    }
    n=(int)value.size();
    vector<int> All_A(n,0);
    vector<int> All_B(n,0);
    vector<int> dpA(A+1,0);
    vector<int> dpB(B+1,0);
    for(int i=0;i<n;++i){
        for(int j=A;j>=weight[i];--j)
            dpA[j]=max(dpA[j],dpA[j-weight[i]]+value[i]);
        All_A[i]=dpA[A];
    }
    for(int i=n-1;i>=0;--i){
        for(int j=B;j>=weight[i];--j)
            dpB[j]=max(dpB[j],dpB[j-weight[i]]+value[i]);
        All_B[i]=dpB[B];
    }
    int combination=0;
    for(int i=0;i<n-1;++i)
        combination=max(combination,All_A[i]+All_B[i+1]);
    cout<<combination;
    return 0;
}

C++ 解法, 执行用时: 4ms, 内存消耗: 456KB, 提交时间: 2020-10-29

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,A,B,maxval = 0;
    int bagA[1002],bagB[1002],ansA[1002],ansB[1002],v[1002],w[1002];
    cin >> n >> A >> B;
    for(int i = 1; i <= n ; i++){
        cin >> v[i] >> w[i];
        for(int j = A; j >= v[i]; j--){
            bagA[j] = max(bagA[j], bagA[j - v[i]] + w[i]);
        }
        ansA[i] = bagA[A];
    }
    
    for(int i = n; i >= 1; i--){
        for(int j = B; j >= v[i]; j--){
            bagB[j] = max(bagB[j], bagB[j - v[i]] + w[i]);
        }
        ansB[i] = bagB[B];
    }
    
    for(int i = 0; i <= n; i++){
        maxval = max(ansA[i] + ansB[i + 1], maxval);
    }
    cout << maxval << endl;
    return 0;
}

上一题