給定n(n<=100)種物品和一個揹包。物品i的重量是wi,價值爲vi,揹包的容量爲C(C<=1000)。問:應如何選擇裝入揹包中的物品,使得裝入揹包中物品的總價值最大? 在選擇裝入揹包的物品時,對每種物品i只有兩個選擇:裝入或不裝入。不能將物品i裝入屢次,也不能只裝入部分物品i。java
共有n+1行輸入: 第一行爲n值和c值,表示n件物品和揹包容量c; 接下來的n行,每行有兩個數據,分別表示第i(1≤i≤n)件物品的重量和價值。算法
輸出裝入揹包中物品的最大總價值。數組
在這裏給出一組輸入。例如:ui
5 10 2 6 2 3 6 5 5 4 4 6
在這裏給出相應的輸出。例如:code
15
這裏採用回溯法,剪枝時以單位質量的價值大小新建一個數組b[],並以其大小爲基準從大到小對b[]數組和物品數組a[][]進行排序,以方便肯定葉結點上界;這裏上界計算方法採用以當前揹包價值value加上揹包剩餘容量乘上當前最大單位價值((c-weight)*b[i]);以b[]數組爲基準同時對a[][]數組和b[]數組同時排序採用快排QuickSort的改寫,具體算法以下:排序
package 宿題;
import java.io.*;
public class PTA0_1Bagpack {
static int n;
static int c;
static double max=0;
static double a[][];
static double b[];
public static void main(String args[])throws IOException{
StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
n=(int)in.nval;
in.nextToken();
c=(int)in.nval;
a=new double[n][2];
b=new double[n];
for(int i=0;i<n;i++){
for(int j=0;j<2;j++){
in.nextToken();
a[i][j]=(double)in.nval;
}
b[i]=a[i][1]/a[i][0];//計算單位質量價值,存入b[]數組;由於b[]數組爲double,爲防止後面出現double轉int形成值丟失,這裏數據都用double儲存;
}
QuickSort(b,0,n-1);
Count(a,0,0,0);
System.out.println((int)max);//由於運算輸出結果爲Int,這裏加一個強制轉換;
}
private static void Count(double a[][],int i,double value,double weight){
if(i==n){//遞歸結束,比較值大小;
if(value>max)
max=value;
}else if(value+(c-weight)*b[i]>=max){//計算結點上界,若是上界小於當前最大值直接結束當前遞歸;
if(a[i][0]+weight<=c)//結點分爲取物品和不取兩個,取物品時判斷揹包容量是否足夠;
Count(a,i+1,value+a[i][1],weight+a[i][0]);
Count(a,i+1,value,weight);
}
}
private static void QuickSort(double a[],int p,int r){//快排算法,在b[]數組值出現互換時同時互換a[][]數組對應的數值;
if(p<r){
int q=Partition(a,p,r);
QuickSort(a,p,q-1);
QuickSort(a,q+1,r);
}
}
private static int Partition(double A[],int p,int r){
int i=p,j=r+1;
double x=A[p];
double x0=a[p][0];
double x1=a[p][1];
while(true){
while(A[++i]>x&&i<r);
while(A[--j]<x);
if(i>=j)
break;
Swap(i,j);
}
A[p]=A[j];
a[p][0]=a[j][0];
a[p][1]=a[j][1];
A[j]=x;
a[j][0]=x0;
a[j][1]=x1;
return j;
}
private static void Swap(int i,int j){
double a1=a[i][1];
double a0=a[i][0];
double b0=b[i];
a[i][1]=a[j][1];
a[i][0]=a[j][0];
b[i]=b[j];
a[j][1]=a1;
a[j][0]=a0;
b[j]=b0;
}
}遞歸
該算法在最壞狀況下的時間複雜度爲O(2^n)。it