主件 | 附件 |
電腦 | 打印機,掃描儀 |
書櫃 | 圖書 |
書桌 | 檯燈,文具 |
工作椅 | 無 |
如果要買歸類爲附件的物品,必須先買該附件所屬的主件。每個主件可以有0個、1個或2個附件。附件不再有從屬於自己的附件。金明想買的東西很多,肯定會超過媽媽限定的N元。於是,他把每件物品規定了一個重要度,分爲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]。(其中*爲乘號)
請你幫助金明設計一個滿足要求的購物單。
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是所屬主件的編號)
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
參考了 https://www.cnblogs.com/mrlaker/archive/2012/07/17/2595345.html 的博文,侵刪!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int m=input.nextInt();
int v[]=new int[m+1];
int w[]=new int[m+1];
int p[]=new int[m+1];
int dp[]=new int[n+1];
int a[][] = new int[m+1][2];
int ww[][] = new int[m+1][4];
int vv[][] = new int[m+1][4];
for(int i=1;i<=m;i++)
{
v[i]=input.nextInt();
w[i]=input.nextInt();
p[i]=input.nextInt();
if(p[i]!=0)
{
if(a[ p[i] ][0]==0)
a[ p[i] ][0]=i;
else
a[ p[i] ][1]=i;
}
}
input.close();
for(int i=1;i<=m;i++)
{
if(p[i]==0)
{
ww[i][0] = v[ i ] * w [ i ];
ww[i][1] = v[ a[i][0] ] * w[ a[i][0] ] + ww[i][0];
ww[i][2] = v[ a[i][1] ] * w[ a[i][1] ] + ww[i][0];
ww[i][3] = v[ a[i][0] ] * w[ a[i][0] ] + v[ a[i][1] ] * w[ a[i][1] ] + ww[i][0];
vv[i][0] = v[i];
vv[i][1] = v[i] + v[ a[i][0] ];
vv[i][2] = v[i] + v[ a[i][1] ];
vv[i][3] = v[i] + v[ a[i][0] ] + v[ a[i][1] ];
}
}
for(int i=1;i<=m;i++)
for(int j=n;j>=v[i];j--)
{
if(p[i]==0)
{
for(int k=0;k<4;k++)
if(j>=vv[i][k])
dp[j]=Math.max(dp[j], dp[j-vv[i][k]]+ww[i][k]);
}
// else
// for(int k=0;k<4;k++)
// if(j>=vv[i][k])
// dp[j]=Math.max(dp[j], dp[j-v[i]]+w[i]);
}
System.out.println(dp[n]);
}
}