問題描述:
主件 | 附件 |
電腦 | 打印機,掃描儀 |
書櫃 | 圖書 |
書桌 | 檯燈,文具 |
工作椅 | 無 |
輸入:
輸入的第 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;
}