華爲OJ購物單

問題描述:

王強今天很開心,公司發給N元的年終獎。王強決定把年終獎用於購物,他把想買的物品分爲兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:

主件附件
電腦打印機,掃描儀
書櫃圖書
書桌檯燈,文具
工作椅

如果要買歸類爲附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個、 1 個或 2 個附件。附件不再有從屬於自己的附件。王強想買的東西很多,爲了不超出預算,他把每件物品規定了一個重要度,分爲 5 等:用整數 1 5 表示,第 5 等最重要。他還從因特網上查到了每件物品的價格(都是 10 元的整數倍)。他希望在不超過 N 元(可以等於 N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
    設第 j 件物品的價格爲 v[j] ,重要度爲 w[j] ,共選中了 k 件物品,編號依次爲 j 1 , j 2 ,……, j k ,則所求的總和爲:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 爲乘號)
    請你幫助王強設計一個滿足要求的購物單。


輸入:

輸入的第 1 行,爲兩個正整數,用一個空格隔開:N m(其中 N ( <32000 )表示總錢數, m ( <60 )爲希望購買物品的個數。)從第 2 行到第 m+1 行,第 j 行給出了編號爲 j-1 的物品的基本數據,每行有 3 個非負整數 v p q(其中 v 表示該物品的價格( v<10000 ), p 表示該物品的重要度( 1 ~ 5 ), q 表示該物品是主件還是附件。如果 q=0 ,表示該物品爲主件,如果 q>0 ,表示該物品爲附件, q 是所屬主件的編號)


輸出:

 輸出文件只有一個正整數,爲不超過總錢數的物品的價格與重要度乘積的總和的最大值( <200000 )。


樣例輸入:

1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0

樣例輸出:2200


我的代碼如下:

#include <iostream>

using namespace std;

#define max(a,b) (a)>(b)?(a):(b)

typedef struct
{
	int value; //價格
	int priority;//重要度
	int q;//編號,0爲主件,非0爲附件
}product;   //商品
product proVec[60];

int main(void)
{
	int N, m;
	cin >> N;//總錢數
	cin >> m;//物品個數
	
	for (int i = 1; i <= m; i++)
	{
		cin >> proVec[i].value >> proVec[i].priority >> proVec[i].q;
	}

	int *f = new int[N + 1];
	for (int i = 0; i <= N; i++)
		f[i] = 0;

	//01揹包問題,建立一維表記錄歷史最優解
	for (int i = 1; i <= m; i++)
	{
		for (int j = N; j >= 10; j -= 10)
		{
			if (j >= proVec[i].value)
			{
				if (proVec[i].q == 0)//如果爲主件,取加入該主件和不加入該主件,價格*重要度的最大值
				{
					f[j] = max(f[j], f[j - proVec[i].value] + proVec[i].value * proVec[i].priority);
				}
				else
				{
					if (j >= proVec[i].value + proVec[proVec[i].q].value)//如果爲非主件,同時也要加入相對應主件
					{
						f[j] = max(f[j], f[j - proVec[i].value - proVec[proVec[i].q].value] +
							proVec[i].value * proVec[i].priority + proVec[proVec[i].q].value*proVec[proVec[i].q].priority);
					}
				}
			}
		}
	}
	cout << f[N];

	delete[]f;
	return 0;
}


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