HDU 1171 Big Event in HDU——二进制优化多重背包

因为甜品可以拆开,所以我们可以把问题转化成两次独立的多重背包,第一次求价值对应的最小体积,第二次求价值对应的最大体积,然后用第一次求得的体积在第二次的dp数组里找价值的最小值即可

这里偷懒只用了二进制优化,跑得挺慢

#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 5e4 + 10;
const int INF = 0x3f3f3f3f;
int N, V, w[210], v[210], num[210], dp[maxn];
struct Node {
    int w, v;
}node[maxn];
void pack(int flag) {
    int n = 0;
    for (int i = 1; i <= N; i++) {
        int cnt = 0;
        for (int j = 0; cnt + (1<= node[i].v; j--) {
            if (flag == 0) dp[j] = min(dp[j], dp[j-node[i].v] + node[i].w);
            else dp[j] = max(dp[j], dp[j-node[i].v] + node[i].w);
        }
    }
}
void solve() {
    int n, m, p;
    scanf("%d%d%d", &n, &m, &p);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d", &v[i], &w[i], &num[i]);
    }
    N = n;
    V = 50000;
    pack(0);
    int t = INF;
    for (int i = p; i <= V; i++) t = min(t, dp[i]);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d%d", &w[i], &v[i], &num[i]);
    }
    N = m;
    V = 50000;
    pack(1);
    int ans = -1;
    for (int i = 0; i <= V; i++) {
        if (dp[i] >= t) { ans = i; break; }
    }
    if (ans == -1) printf("TAT\n");
    else printf("%d\n", ans);
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) solve();
    return 0;
}

 

你可能感兴趣的:(动态规划)