洛谷p2967/USACO Video Game Troubles(分组背包,好题!)

该博客讨论了洛谷p2967和USACO的Video Game Troubles问题,强调了题目对背包理解的考验。博主分析了初始的TLE解决方案,指出其复杂度为O(2^b * N * V),并对比了0/1背包问题,提出优化思路。通过将问题转化为1/1背包与0/1背包的结合,实现了满足O(N * V)复杂度要求的解法。

题 面 是 中 文 版 题面是中文版


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分析

个人认为这题非常考验对背包的理解!
我尝试把这道题讲清楚吧。
首先见到这题第一感觉就是NOIP2006金明的预算方案。把每一个主件的所有组合记录下来,然后进行分组背包,代码如下:

#include <bits/stdc++.h>
#define N 100005
using namespace std;
int f[N], cnt[55], w[55][1050], v[55][1050], p[11], q[11];
int main(){
    int i, j, k, n, m, a, b, s1, s2;
    scanf("%d%d", &n, &m);
    for(i = 1; i <= n; i++){
        scanf("%d%d", &a, &b);
        for(j = 0; j < b; j++) scanf("%d%d", &p[j], &q[j]);
        for(j = 0; j < (1 << b); j++){
            s1 = s2 = 0;
            for(k = 0; k < b; k++){
                if((1 << k) & j) s1 += p[k], s2 += q[k];
            }
            if(a + s1 > m) continue;
            cnt[i]++;
            w[i][cnt[i]] = a + s1;
            v[i][cnt[i]] = s2;
        }
    }
    for(i = 1; i <= n; i++){
        for(j = m; j >= 0; j--){
            for(k = 1; k <= cnt[i]; k++){
                if(j >= w[i][k]) f[j] = max(f[j], f[j - w[i][k]] + v[i][k]);
            }
        }
    }
    printf("%d", f[m]);
    return 0;
}

但是这是tle的!!!!

因为每个主件的组合数是 2 b 2^b 2b 个,最坏情况下复杂度高达 O ( 2 b ∗ N ∗ V ) O(2^{b}*N*V) O(2

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值