Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	Case := 1
	for {
		scanner.Scan()
		W, _ := strconv.Atoi(scanner.Text())
		if W == 0 {
			break
		}
		scanner.Scan()
		n, _ := strconv.Atoi(scanner.Text())
		w := make([]int, n+1)
		v := make([]int, n+1)
		for i := 1; i <= n; i++ {
			scanner.Scan()
			info := strings.Split(scanner.Text(), ",")
			v[i], _ = strconv.Atoi(info[0])
			w[i], _ = strconv.Atoi(info[1])
		}
		// fmt.Println(v)
		// fmt.Println(w)
		dp := make([][]int, n+1)
		for i := range dp {
			dp[i] = make([]int, W+1)
		}
		maxV := -(1 << 21)
		minW := 1 << 21
		for i := 1; i <= n; i++ {
			for j := 1; j <= W; j++ {
				// fmt.Println(dp)
				if j-w[i] >= 0 {
					dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i])
					if maxV < dp[i][j] {
						maxV = dp[i][j]
						minW = j
					} else if maxV == dp[i][j] {
						minW = min(minW, j)
					}
				} else {
					dp[i][j] = dp[i-1][j]
				}
			}
		}
		fmt.Printf("Case %d:\n", Case)
		Case += 1
		fmt.Println(maxV)
		fmt.Println(minW)
	}
}
func max(x, y int) int {
	if x < y {
		return y
	}
	return x
}
func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

C++: #include <cstdio>
#include <iostream>
#include <map>
#include <vector>

using namespace std;

#define INF (1<<29)
#define mp make_pair
#define pb push_back

typedef vector<int> vi;
typedef vector<vi> vii;
typedef pair<int,int> pii;

int main(){
	int W;
	for( int n = 1; cin >> W; n++ ){
		if( W == 0 ) break;
		int N;
		cin >> N;
		vi v(N), w(N);
		for( int i = 0; i < N; i++ ){
			//cin >> v[i] >> "," >> w[i];
			scanf("%d,%d", &v[i], &w[i]);
		}
		// DP
		pii ans = mp(0,INF);
		vector<vector<pii> > dp(N+1, vector<pii>(W+1,mp(0,0)));
		for( int i = 1; i <= N; i++ ){
			for( int j = 1; j <= W; j++ ){
				if( j-w[i-1] < 0 ){
					dp[i][j].first = dp[i-1][j].first;
					dp[i][j].second = dp[i-1][j].second;
				}else{
					if( dp[i-1][j].first <= dp[i-1][j-w[i-1]].first+v[i-1] ){
						dp[i][j] = mp(dp[i-1][j-w[i-1]].first+v[i-1], dp[i-1][j-w[i-1]].second+w[i-1]);
					}else{
						dp[i-1][j] = mp(dp[i-1][j].first, dp[i-1][j].second);
					}
				}
				if( (ans.first == dp[i][j].first && ans.second> dp[i][j].second) || ans.first < dp[i][j].first ){
					ans = dp[i][j];
				}
			}
		}
		cout << "Case " << n << ":" << endl;
		cout << ans.first << endl;
		cout << ans.second << endl;
	}
}

C++: #include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cctype>
 
#include <iostream>
#include <vector>
#include <deque>
#include <queue>
#include <map>
#include <algorithm>
 
using namespace std;
 
//#define deb_table(arr, w, h) rep(w_n, w){  rep(h_n, h) {cout << arr[w][h] << " "  } cout << endl; }
#define rep(i, n) for(int i = 0; i < n; i++)
 
// P(価値, 重さ)
typedef pair<int ,int> P;
 
class data
{
    public:
        int v;
        int w;
    public:
        data(int a, int b){ v=a; w=b;}
};
 
int case_num=1;
/*
風呂敷の耐えられる重さW(1000 以下)
お宝の数 N
お宝 1 の価値(整数), お宝 1 の重さ( ＜ W:整数)
お宝 2 の価値(整数), お宝 2 の重さ( ＜ W:整数)
.
.
.
お宝 N の価値(整数), お宝 N の重さ( ＜ W:整数)
*/
 
int max( int a, int b)
{
    if(a > b) { return a;}
    else { return b; }
}
 
//
int solve()
{
    int w,n;
    vector<data> v;
    cin >> w;
    //終わりのときは-1を返す
    if(w == 0) { return -1; }
 
    cin >> n;
    int value, weight;
 
    //int dp[n+1][w+1];
    //dp[考えたインデックス][重さ]
    //インデックスは０から数えてnまで　=> [n+1]
    //重さは０から数えてwまで        　=> [w+1]
    int dp[n+1][w+1];
    //dp init
    rep(i,n+1)rep(j,w+1) dp[i][j] = 0;  
 
    rep(i, n)
    {
        scanf("%d,%d" ,&value, &weight);
        v.push_back( data(value, weight) );
    }
 
    //dp[何番目まで考えたか][重さ] = 最大値
 
    rep(i,n+1)
    {
        rep(j,w+1)
        {
            //dp[i][j]から二つ分岐、分岐先ではmaxをとる
            if(0 <= i && i < n && 0 <= j && j  <= w )
            {
                dp[i+1][j] = max(dp[i+1][j] , dp[i][j]);
                if ( j+v[i+1].w <= w )
                {
                    dp[i+1][j + v[i+1].w] = max(dp[i+1][j + v[i+1].w] , dp[i][j] + v[i+1].v);
                }
            }
        }
    }
    /*
    rep(i,n+1){
        cout << "[";
        rep(j,w+1){
            cout << dp[i][j] << " ";
        }
        cout << "]" << endl;
    }
    */
    //maxを取る値の最小の重さを探す
    int least_weight;
    rep(j,w){
         if(dp[n][j] < dp[n][j+1])
         {
             least_weight= j+1;
         }
    }
   
    cout << "Case " << case_num << ":" << endl;
    cout << dp[n][w] << endl;
    cout << least_weight<< endl;
    return 0;
}
 
int main()
{
    while (1)
    {
        if(solve() == -1){ break;};
        case_num++;
    }
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>

using namespace std;

pair<int, int> max(const pair<int, int> &a, const pair<int, int> &b) {
    if (a.first == b.first ? a.second < b.second : a.first > b.first) {
        return a;
    } else {
        return b;
    }
}

#define MAX_W 1001

int main() {
    int W;
    int case_n = 1;
    while (cin >> W, W != 0) {
        int N; cin >> N;
        pair<int, int> dp[N][W+1];
        for (int i = 0; i < N; i++) 
            for (int j = 0; j <= W; j++) 
                dp[i][j] = pair<int, int>(0, 0); // 価値、 重さ
        int value[N];
        int weight[N];
        for (int i = 0; i < N; i++) {
            scanf("%d,%d", value+i, weight+i);
        }

        for (int i = 1; i < N; i++) {
            for (int j = 0; j <= W; j++) {
                if (j < weight[i]) {
                    dp[i][j] = dp[i-1][j];
                } else {
                    dp[i][j] = max(dp[i-1][j], 
                            make_pair(dp[i-1][j-weight[i]].first + value[i], 
                                      dp[i-1][j-weight[i]].second + weight[i]));
                }
            }
        }

        cout << "Case " << case_n << ":" << endl;
        cout << dp[N-1][W].first << endl;
        cout << dp[N-1][W].second << endl;
        case_n++;
    }
    return 0;
}

C++: #include <string>
#include <iostream>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <vector>
 
using namespace std;
 

int main(){
	int n = 1;

	while(true){
		int W, N;
		cin >> W;
		if(W == 0){
			break;
		}

		cin >> N;
		int w[1001];
		int v[1001];
		for(int i = 0; i < N; i++){
			scanf("%d,%d", &v[i], &w[i]);
		}
		vector<int> best(W+1);
		best.assign(best.size(), 0);
		for(int i = 0; i < N; i++){
			for(int j = W; j >= 0; j--){
				if(j == 0 || best[j] != 0){
					if(j+w[i] <= W){
						best[j+w[i]] = best[j]+v[i];
//						cout << "best[" << j+w[i] << "]:" << best[j+w[i]] << endl;
					}
				}
			}
		}
		int m = W;
		for(int i = W; i >= 0; i--){
			if(best[i] >= best[m]){
				m = i;
			}
		}
		cout << "Case " << n++ << ":" << endl;
		cout << best[m] << endl;
		cout << m << endl;
	}
  
    return 0;
}