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.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {

	/**
	 * @param args
	 */
	public static final int VALUE = 0;
	public static final int WEIGHT = 1;
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		doIt();
	}

	@SuppressWarnings("unchecked")
	public static void doIt(){
		Scanner sc = new Scanner(System.in);
		int w = sc.nextInt();
		int numOfData = 0;
		while(w != 0){
			numOfData++;
			int n = sc.nextInt();
			int[][] trs = new int[n][2];
			for(int i = 0; i < n; i++){
				String str = sc.next();
				String[] s = str.split(",");
				trs[i][VALUE] = Integer.parseInt(s[0]);
				trs[i][WEIGHT] = Integer.parseInt(s[1]);
			}
			//print(trs,n);
			//ソートしてみる
			Arrays.sort(trs, new MyComparator());
			//print(trs,n);
			int[] per = new int[w];
			boolean[][] used = new boolean[w][n];
			int maxID = 0;

			for(int i = 1; i <= w; i++){
				int index = i - 1;
				//その重さでの最大の価値を求める
				for(int j = 0; j < n; j++){
					int wg = trs[j][WEIGHT];
					if(wg > i){
						//重さが既に超えていたら
						break;
					}
					if(i - wg > 0){
						int ind = index - wg;
						if(used[ind][j] == false){
							if(per[ind] + trs[j][VALUE] > per[index]){
								per[index] = per[ind] + trs[j][VALUE];
								for(int k = 0; k < n; k++){
									used[index][k] = used[ind][k];
								}
								used[index][j] = true;
							}
						}
					}
					else{
						if(trs[j][VALUE] > per[index]){
							per[index] = trs[j][VALUE];
							Arrays.fill(used[index], false);
							used[index][j] = true;
						}
					}

				}
				if(per[maxID] < per[index]){
					maxID = index;
				}
				//System.out.println(i + " : value = " + per[index]);
			}

			//完成？
			System.out.println("Case " + numOfData + ":");
			System.out.println(per[maxID]);
			System.out.println(maxID + 1);

			w = sc.nextInt();
		}
	}

	public static void printTRS(int[][] trs, int n){
		for(int i = 0; i < n; i++){
			System.out.println(i + " : value = " + trs[i][VALUE] + ", weight = " + trs[i][WEIGHT]);
		}
	}

}

//@SuppressWarnings("unchecked")
class MyComparator implements Comparator{
	public MyComparator(){

	}
	public int compare(Object arg0, Object arg1) {
		// TODO 自動生成されたメソッド・スタブ
		int n1 = ((int[])arg0)[1];
		int n2 = ((int[])arg1)[1];
		return n1 < n2 ? -1 : 1;
	}
}