uva main uvalive spa %d val 好題 ble 更改

題目鏈接:https://cn.vjudge.net/problem/UVALive-7197

題意

需要生產n種(2<=n<=14)零件,每種零件可以用兩種材料制作,對這兩種材料的消耗相同,產出價值不同。
但是一種零件一旦選定原材料就不能更改。
給這兩種原材料的量和各零件生產方案,問生產最大價值多少。

思路

一開始WA好幾次,沒發現原材料就不能更改的條件呵呵。

首先對零件分個類,用第一種材料還是第二種。
然後分別做兩個完全背包即可-_-
總復雜度O(nm2^n)
順便,這種多背包解決問題的思考方向,在另一個題目裏提到了。
關於理解背包的本質,就在那道題了,這道題也是好題。

提交過程

WA 原材料就不能更改
AC

代碼

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxw=2e3+20, INF=0x3f3f3f3f;
const int maxn=100+20;
int n, q, r;
int wei[maxn], val_1[maxn], val_2[maxn];
int f[maxw], g[maxw], ans;
bool vis[maxn];

void compKnap(int dp[], int total, int cost, int val){
    for (int i=cost; i<=total; i++)
        dp[i]=max(dp[i], dp[i-cost]+val);
}

void dfs(int dep){
    if (dep==n+1){
        memset(f, 0, sizeof(f));
        memset(g, 0, sizeof(g));
        for (int i=1; i<=n; i++){
            if (vis[i]) compKnap(f, q, wei[i], val_1[i]);
            else compKnap(g, r, wei[i], val_2[i]);
        }
        ans=max(ans, f[q]+g[r]);
    }else{
        vis[dep]=true; dfs(dep+1);
        vis[dep]=false;dfs(dep+1);
    }
}

int main(void){
    while (scanf("%d", &n)==1 && n!=-1){
        for (int i=1; i<=n; i++)
            scanf("%d%d%d", &wei[i], &val_1[i], &val_2[i]);
        scanf("%d%d", &q, &r);

        ans=0;
        dfs(1);
        printf("%d\n", ans);
    }

    return 0;
}
Time Memory Length Lang Submitted
1699ms None 1020 C++ 5.3.0 2018-08-21 05:35:04

UVALive-7197 Axles 動態規劃 多個背包問題