codeforces 1132E
题意:
给 定 一 个 容 量 为 W 的 背 包 , 给 定 体 积 为 1 — 8 的 八 个 物 体 的 数 量 。 问 最 大 能 装 下 物 品 的 体 积 。 给定一个容量为W的背包,给定体积为1—8的八个物体的数量。问最大能装下物品的体积。 给定一个容量为W的背包,给定体积为1—8的八个物体的数量。问最大能装下物品的体积。
题解:
裸
的
多
重
背
包
,
但
由
于
数
据
很
大
,
作
如
下
转
化
。
裸的多重背包,但由于数据很大,作如下转化。
裸的多重背包,但由于数据很大,作如下转化。
假
设
将
容
量
为
W
的
背
包
分
为
若
干
个
容
量
为
840
(
1
—
8
的
L
C
M
)
的
小
背
包
,
假设将容量为W的背包分为若干个容量为840(1—8的LCM)的小背包,
假设将容量为W的背包分为若干个容量为840(1—8的LCM)的小背包,
那
么
每
个
物
品
都
能
单
独
装
满
小
背
包
。
那么每个物品都能单独装满小背包。
那么每个物品都能单独装满小背包。
将
能
凑
成
840
的
物
品
丢
进
背
包
后
,
剩
下
的
物
品
体
积
必
然
小
于
840
∗
8
。
将能凑成840的物品丢进背包后,剩下的物品体积必然小于840*8。
将能凑成840的物品丢进背包后,剩下的物品体积必然小于840∗8。
接
下
来
仅
需
对
容
量
为
840
∗
8
的
背
包
进
行
处
理
。
接下来仅需对容量为840*8的背包进行处理。
接下来仅需对容量为840∗8的背包进行处理。
- d p [ i ] [ j ] = d p [ i ] [ j ] ∣ d p [ i − 1 ] [ j − k ∗ i ] dp[i][j] = dp[i][j]|dp[i-1][j-k*i] dp[i][j]=dp[i][j]∣dp[i−1][j−k∗i]
#include <bits\stdc++.h>
using namespace std;
typedef long long ll;
const int N = 8400;
ll cnt[9], pre[9];
ll dp[9][N];
int main() {
ll W, sum = 0, w = 0, ans = 0;
cin >> W;
for(int i = 1 ; i <= 8 ; i++){
cin >> cnt[i];
sum += cnt[i]*i;
pre[i] = min(1LL*840/i, cnt[i]);
cnt[i] -= pre[i];
w += min(cnt[i], (max(0LL, W-840)-w)/i)*i;
}
if(sum <= W){
return cout << sum , 0;
}
dp[0][0] = 1;
for(int i = 1 ; i <= 8 ; i++){
for(int j = 0 ; j <= 840*8 ; j++){
for(int k = 0 ; k <= min(pre[i], 1LL*j/i) ; k++){
dp[i][j] = dp[i][j]|dp[i-1][j-k*i];
}
}
}
for(int j = 0 ; j <= W-w ; j++){
if(dp[8][j]){
ans = w+j;
}
}
cout << ans << endl;
return 0;
}