Problem:
泥棒

宝物がたくさん収蔵されている博物館に、泥棒が大きな風呂敷を一つだけ持って忍び込みました。盗み出したいものはたくさんありますが、風呂敷が耐えられる重さが限られており、これを超えると風呂敷が破れてしまいます。そこで泥棒は、用意した風呂敷を破らず且つ最も価値が高くなるようなお宝の組み合わせを考えなくてはなりません。

風呂敷が耐えられる重さ W、および博物館にある個々のお宝の価値と重さを読み込んで、重さの総和が W を超えない範囲で価値の総和が最大になるときの、お宝の価値総和と重さの総和を出力するプログラムを作成してください。ただし、価値の総和が最大になる組み合わせが複数あるときは、重さの総和が小さいものを出力することとします。

Input

複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。

W
N
v1,w1
v2,w2
:
vN,wN

１行目に風呂敷の耐えられる重さを表す整数 W (W ≤ 1,000)、２行目にお宝の数 N (1 ≤ N ≤ 1,000) が与えられます。続く N 行に i 番目のお宝の価値を表す整数 vi (0 ≤ vi ≤ 10,000) とその重さを表す整数 wi (0 ≤ wi ≤ W) の組がそれぞれ１行に与えられます。

W が 0 のとき入力の最後とします。データセットの数は 50 を超えません。

Output

各データセットに対して以下のように出力して下さい。

Case データセットの番号:
風呂敷に入れたお宝の価値総和
そのときのお宝の重さの総和

Sample Input

50
5
60,10
100,20
120,30
210,45
10,4
50
5
60,10
100,20
120,30
210,45
10,4
0

Output for the Sample Input

Case 1:
220
49
Case 2:
220
49

Solution in JAVA (judge verdict: Wrong Answer)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main{
	protected static final int MAX_BAG_WEIGHT = 1000;
	protected static final int MAX_NUM_TREASURES = 1000;
	protected static final int MAX_VALUE = 10000;
	protected static final int WEIGHT = 0;
	protected static final int VALUE = 1;

	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int bagWeight = 0;
		int num_treasures = 0;
		int caseNumber = 1;
		ArrayList<Treasure> treasures;
		Thief thief = new Thief();
		while(true){
			//かばんの最大積載量を受け取る
			bagWeight = Integer.parseInt(br.readLine());
			if(bagWeight == 0) break;
			//異常なかばん最大積載量が入力されたら終了する
			if(bagWeight < 0 || bagWeight > MAX_BAG_WEIGHT) break;
			Bag bag = new Bag(bagWeight);
			thief.setBag(bag);
			//お宝の個数を受け取る
			num_treasures = Integer.parseInt(br.readLine());
			//お宝の数が異常値なら処理を終了する
			if(num_treasures < 1 || num_treasures > MAX_NUM_TREASURES) break;
			//お宝情報を入力から取得
			treasures = new ArrayList<Treasure>();
			for(int i = 0; i < num_treasures; i++){
				String[] inputs = (br.readLine()).split(",");
				int treasureValue = Integer.parseInt(inputs[WEIGHT]);
				int treasureWeight = Integer.parseInt(inputs[VALUE]);
				treasures.add(new Treasure(treasureWeight, treasureValue));
			}
			
			//もっとも軽く、もっとも高価なお宝の組み合わせを選び、かばんにつめる
//			printList(treasures);
			thief.sort(treasures);
			thief.steelTreasures(treasures);
//			printList(treasures);
			
			//かばんの重量とお宝の合計金額を出力する
			System.out.println("Case　" + caseNumber++ + ":");
			System.out.println(bag.getCurrentTreasuresWeight());
			System.out.println(bag.getCurrentTreasuresValue());
		}
	}
	
	private static void printList(ArrayList<Treasure> list){
		System.out.println("current list");
		for(Treasure t : list){
			System.out.println("w:" + t.getWeight() + "v:" + t.getValue() + "v/w:" + t.getValuePerWeight());
		}
	}
}

class Bag{
	private int maxWeight;
	private int currentWeight;
	private ArrayList<Treasure> treasures;
	public Bag(int maxWeight) {
		this.maxWeight = maxWeight;
		treasures = new ArrayList<Treasure>(Main.MAX_NUM_TREASURES);
	}
	public void addTreasure(Treasure treasure){
		treasures.add(treasure);
	}
	public int getMaxWeight() {
		return maxWeight;
	}
	public int getCurrentTreasuresValue(){
		int sumOfValue = 0;
		for(Treasure t : treasures){
			sumOfValue += t.getValue();
		}
		return sumOfValue;
	}
	public int getCurrentTreasuresWeight(){
		int sumOfWeight = 0;
		for(Treasure t : treasures){
			sumOfWeight += t.getWeight();
		}
		return sumOfWeight;
	}
}

class Treasure{
	private int weight;
	private int value;
	private double valuePerWeight;
	public Treasure(int weight, int value) {
		this.weight = weight;
		this.value = value;
		valuePerWeight = (double)value / (double)weight;
	}
	public int getValue() {
		return value;
	}
	public int getWeight() {
		return weight;
	}
	public double getValuePerWeight() {
		return valuePerWeight;
	}
}

class Thief{
	private Bag bag;
	public void setBag(Bag bag) {
		this.bag = bag;
	}
	public void steelTreasures(ArrayList<Treasure> treasuresSorted){
		for(int i = treasuresSorted.size() - 1; i >= 0; i--){
			//重量当たりの価値が高いお宝から重量の許す限り、袋につめる
			if(bag.getCurrentTreasuresWeight() + treasuresSorted.get(i).getWeight() <= bag.getMaxWeight()){
				bag.addTreasure(treasuresSorted.get(i));
			}
			else{
				//DO NOTHING
			}
		}
	}
	
	public void sort(ArrayList<Treasure> treasures){
		Collections.sort(treasures, new Comparator<Treasure>() {
			@Override
			public int compare(Treasure o1, Treasure o2) {
				double w1 = o1.getValuePerWeight();
				double w2 = o2.getValuePerWeight();
				int difference = Double.compare(w1, w2);
//				check result of values comparing
//				System.out.println(w1 + ((difference > 0)? " gt "  : " not gt ") + w2);
				return difference;
			}
		});
	}
	
	public void introduce(){
		System.out.println("My name is Lupin the THIRD.");
	}
}