混合揹包(貪心WA / 動規AC)

描述

一個旅行者有一個最多能裝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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章