描述
一個旅行者有一個最多能裝V公斤的揹包,現在有n件物品,它們的重量分別是W1,W2,...,Wn,它們的價值分別爲C1,C2,...,Cn。有的物品只可以取一次(01揹包),有的物品可以取無限次(完全揹包),有的物品可以取的次數有一個上限(多重揹包)。
求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。
格式
輸入格式
第一行:二個整數,M(揹包容量,M≤200),N(物品數量,N≤30); 第2..N+1行:每行三個整數Wi,Ci,Pi,前兩個整數分別表示每個物品的重量,價值,第三個整數若爲0,則說明此物品可以購買無數件,若爲其他數字,則爲此物品可購買的最多件數(Pi)。
輸出格式
僅一行,一個數,表示最大總價值。
樣例
輸入樣例
10 3
2 1 0
3 3 1
4 5 4
輸出樣例
11
限制
時間限制: 1000 ms
內存限制: 65536 KB
//貪心WA60%
#include<bits/stdc++.h>
using namespace std;
struct goods{
int w;
int c;
int p;
}g[35];
int m, n, sumC=0, tmpW=0, sumW=0;
bool compare(const goods g1, const goods g2) {
if (g1.c == g2.c) {
return g1.w < g2.w;
}
return g1.c > g2.c;
}
int main()
{
scanf ("%d %d", &m, &n);
for (int i=0; i<n; i++) {
scanf ("%d %d %d", &g[i].w, &g[i].c, &g[i].p);
}
sort(g, g+n, compare);
for (int i=0; i<n; i++) {
if (sumW < m) {
if (g[i].p == 0) {
while (1) {
if (sumW == m) {
break;
} else if (sumW > m) {
sumW -= g[i].w;
sumC -= g[i].c;
break;
}
sumW += g[i].w;
sumC += g[i].c;
}
} else if (g[i].p > 0) {
for (int j=0; j<g[i].p; j++) {
if (sumW == m) {
break;
} else if (sumW > m) {
sumW -= g[i].w;
sumC -= g[i].c;
break;
}
sumW += g[i].w;
sumC += g[i].c;
}
if (sumW > m){
sumW -= g[i].w;
sumC -= g[i].c;
}
}
} else if (sumW == m) {
break;
}
}
printf ("%d\n", sumC);
return 0;
}
//DP動規AC
#include<bits/stdc++.h>
using namespace std;
struct goods{
int w;
int c;
int p;
}g[35];
int m, n, sumC=0, tmpW=0, sumW=0, dp[250];
int main()
{
scanf ("%d %d", &m, &n);
for (int i=1; i<=n; i++) {
scanf ("%d %d %d", &g[i].w, &g[i].c, &g[i].p);
}
for (int i=1; i<=n; i++) {
if (g[i].p == 0) {
for (int j=g[i].w; j<=m; j++) {
dp[j] = max(dp[j], dp[j-g[i].w]+g[i].c);
}
} else {
for (int j=1; j<=g[i].p; j++) {
for (int k=m; k>=g[i].w; k--) {
dp[k] = max(dp[k], dp[k-g[i].w]+g[i].c);
}
}
}
}
printf ("%d\n", dp[m]);
return 0;
}