Go: package main

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

const MaxW = 1000
const MaxN = 1000

type Tuple struct {
	Value  int
	Weight int
}

func nextLine(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func solve(w int, n int, vws []Tuple) Tuple {
	var dp [MaxN + 1][MaxW + 1]int

	for i := 0; i < n; i++ {
		for j:= w; j > 0; j-- {
			if j < vws[i].Weight {
				dp[i + 1][j] = dp[i][j]
			} else {
				dp[i + 1][j] = int(math.Max(float64(dp[i][j]), float64(dp[i][j - vws[i].Weight] + vws[i].Value)))
			}
		}
	}

	maxValue := dp[n][w]
	minWeight := w

	for j := w - 1; j > 0; j-- {
		if maxValue == dp[n][j] {
			minWeight = j
		} else {
			break
		}
	}

	return Tuple{Value: maxValue, Weight: minWeight}
}

func main() {
	var sc = bufio.NewScanner(os.Stdin)
	index := 1
	for {
		var w, n int
		w, _ = strconv.Atoi(nextLine(sc))
		if w == 0 {
			return
		}
		n, _ = strconv.Atoi(nextLine(sc))

		vws := make([]Tuple, n, n)
		for i := 0; i < n; i++ {
			array := strings.Split(nextLine(sc), ",")
			v, _ := strconv.Atoi(array[0])
			w, _ := strconv.Atoi(array[1])
			vws[i] = Tuple{Value: v, Weight: w}
		}

		t := solve(w, n, vws)
		fmt.Printf("Case %d:\n", index)
		fmt.Println(t.Value)
		fmt.Println(t.Weight)
		index++
	}
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;

int W, N;
int v[1000], w[1000], dp[1000+1][1000+1];

int main()
{
  int cnt = 1;
  while (~scanf("%d", &W)) {
    if (W == 0)
      break;

    for (int i = 0; i < 1001; ++i) {
      for (int j = 0; j < 1001; ++j)
	dp[i][j] = 0;
    }

    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
      scanf("%d,%d", &v[i], &w[i]);

    int maxV = -1, minW = 1 << 30;
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < W+1; ++j) {
	if (j < w[i]) {
	  dp[i+1][j] = dp[i][j];
	} else {
	  dp[i+1][j] = max(dp[i+1][j], dp[i][j-w[i]]+v[i]);
	  if (maxV < dp[i+1][j]) {
	    maxV = dp[i+1][j];
	    minW = j;
	  } else if (maxV == dp[i+1][j]) {
	    minW = min(minW, j);
	  }
	}
      }
    }

    printf("Case %d:\n", cnt++);
    printf("%d\n%d\n", maxV, minW);
  }
  return 0;
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<climits>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<memory>
#include<functional>
#include<set>
 
using namespace std;
 
#define ALL(g) (g).begin(),(g).end()
#define REP(i, x, n) for(int i = x; i < n; i++)
#define rep(i,n) REP(i,0,n)
#define F(i,j,k) fill(i[0],i[0]+j*j,k)
#define P(p) cout<<(p)<<endl;
#define INF 1<<25
 
typedef long long ll;

int dy[8]={1,1,1,0,0,-1,-1,-1};
int dx[8]={-1,0,1,-1,1,-1,0,1};
struct S{
	int a,b,c;
};
bool asc(const S& left,const S& right){
	return left.c > right.c;
}

int W,N;
int v[1001],w[1001];
int dp[1001][1001];

int main(){
	int cnt=1;
	while(1){
		cin>>W;
		if(W==0)break;
		cin>>N;
		rep(i,N)cin>>v[i]>>w[i];
		REP(i,1,N+1){
			rep(j,W+1){
				if(w[i-1]<=j)
					dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i-1]]+v[i-1]);
				else 
					dp[i][j]=dp[i-1][j];
			}
		}
		int ans_v=0,ans_w=0;
		rep(i,W+1){
			if(dp[N][i]>ans_v){
				ans_v=dp[N][i];
				ans_w=i;
			}
		}
		cout<<"Case "<<cnt<<endl;
		cout<<ans_v<<endl;
		cout<<ans_w<<endl;
		cnt++;
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
//#include <stack>
//#include <queue>
//#include <map>
#include <cmath>
//#include <string>
//#include <sstream>
#include <iomanip>
//#include <complex>
#include <stdio.h>
//小数制度 	cout << fixed << setprecision(5) << tmp << endl;
using namespace std;

#define ll long long
#define vvi vector< vector<int> >
#define All(X) X.begin(),X.end()
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define REP(i,n) for(int i=0;i<(int)(n);i++)

int dp[1010][1010];
int v[1010];
int w[1010];
int main(){
  int wei,n;
  int cnt = 1;
  while(cin >> wei,wei){
    cin >> n;
    REP(i,1010) REP(j,1010) dp[i][j] = 0;
    w[0]=0;v[0]=0;
    for(int i=0;i<n;i++){
      scanf("%d,%d",&v[i],&w[i]);
    }
    for(int i=0;i<n;i++){
      for(int j=0;j<=awei;j++){
        if(j-w[i]<0) dp[i+1][j] = dp[i][j];
        else  dp[i+1][j]=max(dp[i][j+1],dp[i+1][j-w[i]]+v[i]);
      }
    }
    /*for(int i=0;i<n+1;i++){
      for(int j=0;j<wei+1;j++){
        cout << dp[i][j] << " ";//l<<endl;
      }
      cout << endl;
    }*/
    int maxv=0;
    int ans=-1;
    for(int i=0;i<wei+1;i++){
      if(maxv < dp[n][i]){
        maxv = dp[n][i];
        ans = i;
      }
    }
    cout << "Case " << cnt << ":" <<endl;
    cout << maxv << endl << ans << endl;
    cnt++;
  }
}

C++: #include<iostream>
using namespace std;
int max(int n,int m){
  return(n>m?n:m);
}
int main(){
  int nap; //重さ
  int n;//お宝の数
  int c = 1;
  int ans = 0;
  int ans2 = 0;
  int mv = 0; //最大の重さ
  int cach; //価値の合計
  while(cin>>nap){
    if(nap==0) break;
    cin >> n;
  int so[nap+1]; //総数
  int kach[n]; //価値
  int val[n]; //重さ
  char a;
  for(int i=1;i<=nap;i++){ 
    so[i] = -1;
    so[0] = 0;
  }
  for(int i=0;i<n;i++){
    cin >> kach[i] >> a >> val[i];
    mv = nap - val[i];
    for(int j=mv;j>=0;j--){
      if(so[j]!=-1){
	cach = kach[i] + so[j];
	so[val[i]+j] = max(so[val[i]+j],cach);
      }
    }
  }
  for(int i=0;i<=nap;i++){
    if(ans<so[i]){
      ans = so[i];
      ans2 = i;
    }
}    
  cout << "Case " << c++ << ':' << endl;
  cout << ans << endl << ans2 << endl;
  ans = 0;
  ans2 = 0;
}
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;

int main(void){
	int i,j;
	int n,tmp;
	vector<int> v,w;
	int max_w;
	int cur=0,nxt=1;
	int dp[2][10001];
	int index=0;
	int tmp_max = 0;
	
	while(cin >> max_w){
		if(max_w == 0) break;
		memset(dp, 0, sizeof(dp));
		cur = 0;
		nxt = 1;
		cin >> n;
		for(i=0;i<n;i++){
			cin >> tmp;
			v.push_back(tmp);
			cin.ignore();
			cin >> tmp;
			w.push_back(tmp);
		}
		//f[^ÇÝÝ±±ÜÅ
		
		/*
		*  dp[i+1][j] := iÔÚÜÅÅd³jÉµ½Æ«ÌÅåÌ¿l
		*  dp[i+1][j] = max(dp[i][j], dp[i][j-w[i]] + v[i]) if(j > w[i])
		*  dp[i+1][j] = dp[i][j]
		*/
		for(i=0;i<n;i++){
			for(j=0;j<=max_w;j++){
				if(j >= w[i]){
					dp[nxt][j] = max(dp[cur][j], dp[cur][j-w[i]] + v[i]);
				}else{
					dp[nxt][j] = dp[cur][j];
				}
				//cout << dp[nxt][j] << " ";
			}
			nxt = 1 - nxt; //toggle
			cur = 1 - cur; //toggle
			//cout << endl;
		}
		
		cout << dp[cur][max_w] << endl;
		for(i=0;i<=max_w;i++){
			if(tmp_max < dp[cur][i]){
				tmp_max = dp[cur][i];
				index = i;
			}
		}
		cout << index << endl;
		v.clear();
		w.clear();
		index = 0;
		tmp_max=0;
	}
	
	
}