洛谷-【動態規劃】-P2623 物品選取
阿新 • • 發佈:2018-12-15
題目背景
小X確信所有問題都有個多項式時間演算法,為了證明,他決定自己去當一次旅行商,在上路之前,小X需要挑選一些在路上使用的物品,但他只有一個能裝體積為m的揹包。顯然,揹包問題對小X來說過於簡單了,所以他希望你來幫他解決這個問題。
題目描述
小X可以選擇的物品有n樣,一共分為甲乙丙三類:
1.甲類物品的價值隨著你分配給他的揹包體積變化,它的價值與分配給它的體積滿足函式關係式,v(x) = A*x^2-B*x,A,B是每個甲類物品的兩個引數。注意每個體積的甲類物品只有一個。
2.乙類物品的價值A和體積B都是固定的,但是每個乙類物品都有個引數C,表示這個物品可供選擇的個數。
3.丙類物品的價值A和體積B也是固定的,但是每個丙類物品可供選擇的個數都是無限多個。
你最終的任務是確定小X的揹包最多能裝有多大的價值上路。
輸入輸出格式
輸入格式:
第一行兩個整數n,m,表示揹包物品的個數和揹包的體積;
接下來n行,每行描述一個物品的資訊。第一個整數x,表示物品的種類:
若x為1表示甲類物品,接下來兩個整數A, B,為A類物品的兩個引數;
若x為2表示乙類物品,接下來三個整數A,B,C。A表示物品的價值,B表示它的體積,C表示它的個數;
若x為3表示丙類物品,接下來兩個整數A,B。A表示它的價值,B表示它的體積。
輸出格式:
輸出檔案僅一行為一個整數,表示小X的揹包能裝的最大價值。
輸入輸出樣例
輸入樣例#1: 複製
1 0 1 1 1
輸出樣例#1: 複製
0
輸入樣例#2: 複製
4 10 2 1 2 1 1 1 2 3 5 2 2 200 2 3
輸出樣例#2: 複製
610
說明
對於50%的資料,只有乙和丙兩類物品;
對於70%的資料,1<=n<=100, 1<=m<=500,0<=A,B,C<=200;
對於100%的資料,1<=n<=100, 1<=m<=2000,0<=A,B,C<=200;
題解:混合揹包問題,對甲類物品來說是01揹包,對乙類物品來說是完全揹包,對丙類物品來說是多重揹包問題,如果對揹包問題足夠了解的話,本題很好解答,。
import java.util.*; /* *物品選取 */ public class Main{ static int a,b; public static int v(int x) { return (int) (a*x*x-b*x); } public static void main(String[] args) { Scanner in=new Scanner(System.in); int n=in.nextInt(); int m=in.nextInt(); int[] dp=new int[2020]; for(int i=1;i<=n;i++) { int x=in.nextInt(); a=in.nextInt(); b=in.nextInt(); if(x==1) { for(int j=m;j>=1;j--) { for(int k=1;k<=j;k++) { dp[j]=Math.max(dp[j-k]+v(k), dp[j]); } } }else if(x==2) { int c=in.nextInt(); for(int j=m;j>=b;j--) { for(int k=1;k<=c;k++) { if(j-k*b<0) break; dp[j]=Math.max(dp[j-k*b]+k*a, dp[j]); } } }else if(x==3) { for(int j=b;j<=m;j++) { dp[j]=Math.max(dp[j-b]+a, dp[j]); } } } System.out.println(dp[m]); } }