这是一道比CCCC简单题经典的中档题
Time Limit: 4500/1500MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)Submit Status
谭爷曾经是个很爱喝豆奶的男人,UESTC小卖部有N种豆奶,每种豆奶的数量为C1,C2......Cn。谭爷在抢劫小卖部的时候会从中任选若干件放在容量为W的谭爷巨型背包里,每种豆奶的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的豆奶最大价值。
Input
第1行,两个整数N和W,中间用空格隔开。N为豆奶的种类数,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000) 第2 - N + 1行,每行3个整数Wi,Pi和Ci,分别是豆奶体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)Output
谭爷可以抢到的最大的豆奶价值之和。Sample input and output
Sample Input Sample Output
3 6 9
2 2 5
3 3 8
1 4 1
Source
2017 UESTC Training for Dynamic Programming
My Solution
多重背包
转化成0-1背包来跑。
for(i = 1; i <= n; i++){
for(k = 0; k <= c[i]; k++){
for(j = w; j >= 0; j--){
if(j - k*need[i] >= 0) dp[i][j] = max(dp[i][j], dp[i-1][j-k*need[i]] + k*value[i]);
else break;
}
}
for(j = 0; j <= w; j++){
if(j) dp[i][j] = max(dp[i][j], dp[i][j-1]);
}
}
时间复杂度 O(n*sigma(ci))
空间复杂度 O(n^w)
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
const int MAXN = 1e2 + 8, MAXM = 5e4 + 8;
int need[MAXN], value[MAXN], c[MAXN], dp[MAXN][MAXM];
template <class T>
inline void cinn(T &ret)
{
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
ret=c-'0';
while(c=getchar(),c>='0'&&c<='9')
ret=ret*10+(c-'0');
}
int main()
{
#ifdef LOCAL
freopen("m.txt", "r", stdin);
//freopen("m.out", "w", stdout);
#endif // LOCAL
//ios::sync_with_stdio(false); cin.tie(0);
int n, w, i, j, k;
//cin >> n >> w;
//scanf("%d%d", &n, &w);
cinn(n); cinn(w);
for(i = 1; i <= n; i++){
//cin >> need[i] >> value[i];
//scanf("%d%d%d", &need[i], &value[i], &c[i]);
cinn(need[i]); cinn(value[i]); cinn(c[i]);
}
for(i = 1; i <= n; i++){
for(k = 0; k <= c[i]; k++){
for(j = w; j >= 0; j--){
if(j - k*need[i] >= 0) dp[i][j] = max(dp[i][j], dp[i-1][j-k*need[i]] + k*value[i]);
else break;
}
}
for(j = 0; j <= w; j++){
if(j) dp[i][j] = max(dp[i][j], dp[i][j-1]);
}
}
//cout << dp[n-1][w] << endl;
printf("%d\n", dp[n][w]);
return 0;
}
Thank you!
------from ProLights