zcmu1368 : 동적 프로그래밍 (여러 백팩)

제목 링크 : https://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1368

이야기

n 종류의 아이템, 배낭 용량 w. 각 항목에는 wi의 볼륨, vi 및 ci의 값이 있습니다. 배낭이 취할 수있는 최대 가치를 찾으십시오.

范围 : (1 <= n <= 100, 1 <= w <= 50000, 1 <= wi <= 10000, 1 <= vi <= 10000, 1 <= ci <= 200)

아이디어

여러 배낭 누드 질문. 총 부피가 배낭 용량보다 크거나 같으면 완전한 배낭을 따릅니다. 그렇지 않으면 01 배낭을 충족하려면 숫자 ci를 1, 2, 4 및 9 = 1 + 2 + 4 + 2와 같은 다른 이진수로 더하고 네 부분으로 나누고 볼륨 값을 두 배로 늘린 다음 01 배낭 작업을 수행합니다.

ac 코드

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int dp[maxn];
int weight[maxn], value[maxn], num[maxn];
int n, s;
void bag1(int w, int v){ //01背包
    for(int i = s; i >= w; i --)
        dp[i] = max(dp[i], dp[i - w] + v);
}
void bag2(int w, int v){ //完全背包
    for(int i = w; i <= s; i ++)
        dp[i] = max(dp[i], dp[i - w] + v);
}
void bag3(int w, int v, int num){ //多重背包
    if(num * w >= s) bag2(w, v);
    else{
        int k = 1;
        while(k <= num){
            bag1(k * w, k * v);
            num -= k;
            k <<= 1;
        }
        bag1(num * w, num * v); //最后剩下的
    }
}
int main(){
    while(~scanf("%d%d", &n, &s)){
        for(int i = 1; i <= n; i ++){
            scanf("%d%d%d", &weight[i], &value[i], &num[i]);
        }
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i ++){
            bag3(weight[i], value[i], num[i]); //对每种物品做多重背包
        }
        printf("%d\n", dp[s]);
    }
    return 0;
}

 

추천

출처blog.csdn.net/weixin_43911947/article/details/113361733