package com.ltcode.ds;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
public class CeShi61 {
static class Element implements Comparable<Element> {
int ID;
int d;
public Element() {}
public Element(int ID, int d) {
this.ID = ID;
this.d = d;
}
@Override
public int compareTo(Element e) {
if(this.d > e.d) return -1;
if(this.d == e.d) return 0;
return 1;
}
}
static class BBNode {
BBNode parent;
boolean leftChild;
public BBNode() {}
public BBNode(BBNode parent, boolean leftChild) {
this.parent = parent;
this.leftChild = leftChild;
}
}
static class HeapNode implements Comparable<HeapNode> {
int upProfit;
int profit;
int weight;
int level;
BBNode ptr;
public HeapNode() {}
public HeapNode(int upProfit, int profit, int weight, int level, BBNode ptr) {
this.upProfit = upProfit;
this.profit = profit;
this.weight = weight;
this.level = level;
this.ptr = ptr;
}
@Override
public int compareTo(HeapNode node) {
if (this.upProfit > node.upProfit) return -1;
if (this.upProfit == node.upProfit) return 0;
return 1;
}
}
public static int c;
public static int n;
public static int[] w;
public static int[] p;
public static int cw;
public static int cp;
public static int[] bestx;
public static LinkedList<HeapNode> H;
public static BBNode E;
public static int bound(int i){
int cleft = c - cw;
int b = cp;
while (i<=n && w[i]<=cleft) {
cleft -= w[i];
b += p[i];
i++;
}
if (i <= n) {
b += p[i]/w[i] * cleft;
}
return b;
}
public static void addLiveNode(int up, int cp, int cw, boolean ch, int lev){
BBNode b = new BBNode(E, ch);
HeapNode N = new HeapNode(up, cp, cw, lev, b);
H.add(N);
Collections.sort(H);
}
public static int maxKnapsack(){
H = new LinkedList<HeapNode>();
bestx = new int[n+1];
int i = 1;
E = null;
cw = cp = 0;
int bestp = 0;
int up = bound(1);
while (i != n+1) {
int wt = cw + w[i];
if (wt <= c) {
if(cp+p[i] > bestp){
bestp = cp + p[i];
}
addLiveNode(up,cp+p[i],cw+w[i],true,i+1);
}
up = bound(i+1);
if (up >= bestp) {
addLiveNode(up, cp, cw,false,i+1);
}
HeapNode node = H.poll();
E = node.ptr;
cw = node.weight;
cp = node.profit;
up = node.upProfit;
i = node.level;
}
for (int j = n; j > 0; j--) {
bestx[j] = E.leftChild ? 1:0;
E = E.parent;
}
return cp;
}
public static int knapsack(int[] pp, int[] ww, int cc, int nn, int[] xx){
int ws = 0,
ps = 0;
Element[] Q = new Element[nn];
for (int i = 1; i <= nn; i++) {
Q[i-1] = new Element(i,pp[i]/ww[i]);
ps += pp[i];
ws += ww[i];
}
if (ws <= cc) {
for(int i = 1; i <= nn; i++){
xx[i] = 1;
}
return ps;
}
Arrays.sort(Q);
p = new int[nn + 1];
w = new int[nn + 1];
for (int i = 1; i <= nn; i++) {
p[i] = pp[Q[i-1].ID];
w[i] = ww[Q[i-1].ID];
}
cp = 0;
cw = 0;
c = cc;
n = nn;
int bestp = maxKnapsack();
for (int j = 1; j <= nn; j++) {
xx[Q[j-1].ID] = bestx[j];
}
return bestp;
}
public static void main(String[] args) {
c = 30;
n = 3;
w = new int[]{0, 16, 15, 15};
p = new int[]{0, 45, 25, 25};
int[] xx = new int[n + 1];
int maxp = knapsack(p, w, c, n, xx);
System.out.println("装入背包中物品总价值最大为:" + maxp);
System.out.print("装入的物品的最优序列为:");
for(int i = 1; i <= n; i++){
System.out.print(bestx[i] + " ");
}
}
}