P2306 被yyh虐的mzc
P2306 被yyh虐的mzc
容量为 \(V\), 有 \(n\) 件物品, 反正直接背包绝对超时 , 每个有重量和价值 \(a_{i}, b_{i}(a_{i}, b_{i} <= 10)\) 求最大价值
错误日志: V 和 Max 读反了哇我真是个傻逼
Solution
发现数据范围有鬼: \((a_{i}, b_{i} <= 10)\) , 联想到可能有相同属性的物品重复出现
于是使用二进制优化的多重背包解决问题
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
using namespace std;
LL RD(){
    LL out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const LL maxn = 2000019;
LL num, V;
LL v[maxn], w[maxn], cnt;
LL dp[maxn];
int main(){
	num = RD(), V = RD();
	for(LL i = 1;i <= num;i++){
		LL val = RD(), wei = RD(), n = RD(), t = 1;
		while(n >= t){
			v[++cnt] = val * t, w[cnt] = wei * t;
			n -= t;
			t <<= 1;
			}
		v[++cnt] = val * n, w[cnt] = wei * n;
		}
	for(LL i = 1;i <= cnt;i++){
		for(LL j = V;j >= w[i];j--){
			dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
			}
		}
	printf("%lld\n", dp[V]);
	return 0;
	}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号