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 <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define FOR(I,F,N) for(int I = F; I < (int)(N); I++)
#define rep(i, n) FOR(i, 0, n)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 28)
 
template<typename T>
void remove(vector<T>& vector, unsigned int index){
vector.erase(vector.begin() + index);
}
 
typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
 
int W, N;
int tres[1001];
int weig[1001];
int maxW, maxV;
int dp[1001][1001];
 
void dfs(int weight, int value, int index){
	if(can[index] < maxV)return;
    if(weight > W)return;
    if(dp[weight][index]>value)return;
    dp[weight][index] = value;
    if(index == N){
        if(maxV < value){
            maxW = weight;
            maxV = value;
        }else if(maxV == value){
            if(maxW > weight){
                maxW = weight;
                maxV = value;
            }
        }
        return;
    }
    if(dp[weight][index+1]<value)dfs(weight, value, index+1);
    if(weight+weig[index] > W)return;
    if(dp[weight+weig[index]][index+1]<value+tres[index])dfs(weight+weig[index], value+tres[index], index+1);
}
 
 
int main(void){
    int cnt = 0;
    while(cin >> W, W){
        cnt++;
        cin >> N;
        maxW = 0;
        maxV = 0;
        // fill_n(tres, 1001, 0);
        // fill_n(weig, 1001, 0);
        fill_n(*dp, 1001*1001, -1);
 
        rep(i,N){
            int n, w;
            scanf("%d,%d", &n, & w);
            tres[i] = n;
            weig[i] = w;
            if(i==0)can[i]=tres[i];
            else can[i] = can[i-1]+tres[i];
        }
 
        dfs(0,0,0);
        cout << "Case " << cnt << ":" << endl;
        cout << maxV << endl << maxW << endl;
    }
 
    return 0;
}
 
 
 
int StrToInt(string s){
    stringstream ss;
    ss << s;
    int val;
    ss >> val;
    return val;
}
string IntToStr(int i){
    stringstream ss;
    ss << i;
    return ss.str();
}

C++: #include <stdio.h>

typedef struct{
	int sum_v;
	int sum_w;
}tre;

int max_w, n, v[1000], w[1000];
int sum_w;
tre memo[1001][1001];

tre dp(int i, int j);

int main(void){
	int num = 1;
	int i, j;
	tre treasure;

	while(1){
		scanf("%d", &max_w);
		if(max_w == 0) break;
		scanf("%d", &n);
		for(i=0; i<n; i++){
			scanf("%d,%d", &v[i], &w[i]);
		}

		for(i=0; i<1001; i++){
			for(j=0; j<1001; j++){
				memo[i][j].sum_v = -1;
				memo[i][j].sum_w = -1;
			}
		}

		treasure = dp(0, max_w);
		printf("Case %d:\n", num);
		printf("%d\n", treasure.sum_v);
		printf("%d\n", treasure.sum_w);
		num++;
	}

	return 0;
}

tre dp(int i, int j){
	if((memo[i][j]).sum_v >= 0){
		return memo[i][j];
	}

	tre t;
	tre temp_1, temp_2;
	int in, notin;
	if(i == n){
		t.sum_v = 0;
		t.sum_w = 0;
	}else if(j < w[i]){
		t.sum_v = dp(i+1, j).sum_v;
	}else{
		temp_1 = dp(i+1, j);
		temp_2 = dp(i+1, j-w[i]);

		notin = temp_1.sum_v;
		in = temp_2.sum_v + v[i];

		if(temp_2.sum_v + v[i] > temp_1.sum_v){
			t.sum_v = temp_2.sum_v + v[i];
			t.sum_w = temp_2.sum_w + w[i];
		}else if(temp_2.sum_v + v[i] < temp_1.sum_v){
			t.sum_v = temp_1.sum_v;
			t.sum_w = temp_1.sum_w;
		}else{
			if(temp_2.sum_w + w[i] > temp_1.sum_w){
				t.sum_v = temp_1.sum_v;
				t.sum_w = temp_1.sum_w;
			}else{
				t.sum_v = temp_2.sum_v + v[i];
				t.sum_w = temp_2.sum_w + w[i];
			}
		}
	}
	return memo[i][j] = t;
}

C++: #include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include <utility>
using namespace std;
int main(){
int dp[10100];
int W,N;
int v[1010],w[1010];
int count=0;
while(cin>>W,W){
cin>>N;
count++;
for(int i=0;i<N;i++){
scanf("%d,%d",&v[i],&w[i]);
}
for(int j=0;j<W+1;j++){
if(j<w[0]){
dp[j]=0;
}else{
dp[j]=v[0];
}
}
for(int i=1;i<N;i++){
for(int j=W;j;j--){
if(j<w[i]){
dp[j]=dp[j];
}else{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
}
cout<<"Case "<<count<<":"<<endl;
cout<<dp[W]<<endl;
while(dp[W]==dp[W-1])W--;
cout<<W<<endl;
}
return 0;
}

C++: #include<stdio.h>
int i,j,l;
int w;
int n;
int kati,omosa;
int casecnt=0;
long long int dp[1010][1010];//dp[お宝の総数][お宝の重さ]
int main(void){
	scanf("%d",&w);
	while(w!=0){
		for(i=0;i<=n;i++){
			for(j=0;j<=w;j++){
				if(j>0){
					dp[i][j]=-1;
				}
				else {
					dp[i][j]=0;
				}
			}
		}
		scanf("%d",&n);
		for(i=0;i<n;i++){
			scanf("%d,%d",&kati,&omosa);
			for(j=0;j<=w;j++){
				if(dp[i][j]>=0){
					if(dp[i+1][j+omosa]<kati){
						dp[i+1][j+omosa]=dp[i][j]+kati;
					}
				}
			}
			for(j=0;j<=w;j++){
				if(dp[i+1][j]<dp[i][j]){
					dp[i+1][j]=dp[i][j];
				}
			}
		}
		for(i=0;i<=n;i++){
			for(j=0;j<=w;j++){
				printf("%d ",dp[i][j]);
			}
			printf("\n");
		}
		int maxkati=0,maxomosa=0;
		for(j=0;j<=w;j++){
			if(maxkati<dp[n][j]){
				maxkati=dp[n][j];
				maxomosa=j;
			}
		}
		casecnt++;
		printf("case %d:\n",casecnt);
		printf("%d\n",maxkati);
		printf("%d\n",maxomosa);
		scanf("%d",&w);
	}
	return 0;
}

C++: #include<iostream>

using namespace std;

const int MAX_W = 1001;
const int MAX_T = 1001;

int dp[MAX_T][MAX_W];

void init(){
  for(int i = 0; i < MAX_T; i++){
    fill(dp[i],dp[i]+MAX_W,0);
  }
}

int main(){
  int rev = 0, max;
  while(cin >> max && max){
    rev++;
    init();
    int num;
    cin >> num;
    for(int i = 0; i < num; i++){
      char trash;
      int price, weight;
      cin >> price >> trash >> weight;
      for(int j = 1; j <= max; j++){
	if(weight <= j){
	  dp[i][j] = price;
	  if(i)dp[i][j]+= dp[i-1][j-weight];
	}
      }
    }
    int ablep = 0, ablew = 10000;
    for(int i = 0; i < num; i++){
      for(int j = 0; j <= max; j++){
	if(ablep < dp[i][j]){
	  ablep = dp[i][j];
	  ablew = j;
	}else if(ablep == dp[i][j]){
	  if(ablew > j) ablew = j;
	}
      }
    }
    cout << "Case " << rev << ":" << endl;
    cout << ablep << endl << ablew << endl;

  }
  return 0;
}