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>

using namespace std;

int main(void){
  int W,n,v[1000],w[1000],dp[1000][1000],t=1;

  while(cin >> W,W){
    cin >> n;

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

    for(int i=0;i<1000;i++)
      for(int j=0;j<1000;j++)
	dp[i][j]=-1;
    
    for(int i=0;i<1000;i++){
      dp[0][i] = 0;
    }
    
    for(int i=0;i<n;i++)
      for(int j=0;j<=W;j++)
	if(j<w[i])dp[i+1][j]=dp[i][j];
	else dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]);

    cout << "Case " << t << ":" << endl;
    
    for(int i=W-1;i>=0;i--){
      if(dp[n][i] != dp[n][W]){
	cout << dp[n][W] << endl << i+1 << endl;
	break;
      }
    }
      t++;
  }

  return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<string>
#include<typeinfo>
#include<cstdlib>
using namespace std;
int b[1000][1001];
int main() {
	int w, n;
	int sum = 1;
	while (cin >> w&&w != 0) {
		cin >> n;
		int a[1000][2];	
		for (int i = 0; i < n; i++) {
			string h;
			cin >> h;
			h += ",";
			string k="";
			int l = 0;
			for (int j = 0; j < h.length(); j++) {
				if (h[j] == ',') {
					a[i][l] = atoi(k.c_str());
					k = "";
					l++;
				}
				else
					k += h[j];
			}
		}
		int sum1 = 0 ,sum2 = 1002;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < w; j++) {
				b[i][j] = 0;
				if (j == 0) b[i][j] = 0;
			}
		}
		b[0][a[0][1]] = a[0][0];
		for (int i = 1; i < n; i++) {
			for (int j = 0; j <= w; j++) {
				if (j - a[i][1] >= 0) {
					b[i][j] = max(b[i - 1][j], b[i][j - a[i][1]] + a[i][0]);
				}
			}
		}
		for (int i = w; i >= 0; i--) {
			if (b[n - 1][i] >= sum1) {
				sum1 = b[n - 1][i];
				sum2 = i;
			}
		}
		cout << "Case " << sum << ":" << endl;
		cout << sum1 << "\n" << sum2 << endl;
		sum++;
	}
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;
int N, W, maxW;
int w[1001], v[1001];
int dp[1001][1001];
int c;

void solve() {
    for (int i = 0; i <= W; i++) dp[N][i] = 0;
    for (int i = 0; i < N; i++) dp[i][0] = 0;

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

    }
    printf("Case %d:\n", c);
    printf("%d\n%d\n", dp[0][W], maxW);
}

int main()
{
    c = 1;
    for (; ;) {
        scanf("%d", &W);
        if (W == 0) break;
        scanf("%d", &N);
        for (int i = 0; i < N; i++) scanf("%d,%d", &v[i], &w[i]);
        solve();
        c++;
    }
    return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define latte WORLD

int N,W,tv[1000],tw[1000];
int memo[1000][1001],ansv,answ;

int latte(int n,int v,int w){
    if(w<=0) return 0;
    if(n==N){
        if(ansv<v || (ansv==v && w>answ)){
            ansv = v; answ = w;
        }
        return v;
    }
    if(memo[n][w]!=-1) return memo[n][w];
    memo[n][w] = max(latte(n+1,v+tv[n],w-tw[n]),latte(n+1,v,w));
    return memo[n][w];
}

int main(){
    for(int ds=1;cin>>W,W;ds++){
        cin>>N;
        for(int i=0;i<N;i++) scanf("%d,%d",&tv[i],&tw[i]);
        fill_n((int*)memo,1000*1001,-1);
        ansv = 0;
        latte(0,0,W);
        printf("Case %d:\n%d\n%d\n",ds,ansv,W-answ);
    }
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define REP(n) rep(i,n)
#define onen(i,n) for(int i=1;i<n+1;i++)

const int MAXW = 1001, MAXN = 10001;
int dp[MAXN][MAXW],w[MAXN], v[MAXN];
int n, maxw;

int main()
{
    int setnum = 1;
    while(cin >> maxw && maxw)
    {
        memset(dp, 0, sizeof(dp));
        char t;
        
        cin >> n;
        REP(n)cin >> v[i] >> t >> w[i];

        rep(i,n)onen(j,maxw)
        {
            dp[i+1][j] = max(dp[i+1][j], dp[i][j-1]);
            if(j>=w[i]) dp[i+1][j] = max(dp[i+1][j], dp[i][j - w[i]] + v[i]);
        }

        int maxv = -1, weight = 0;
        onen(j,maxw)if(dp[n][j] > maxv) { maxv = dp[n][j]; weight = j;}
        
        cout << "Case " << setnum << ":" << endl;
        cout << maxv << endl;
        cout << weight << endl;
        setnum++;
    }

    return 0;

}

C++: #include<bits/stdc++.h>
using namespace std;

int main(){
  int W,N;
  int dp[1001];
  int num = 1;
  while(scanf("%d",&W),W){
    scanf("%d",&N);
    memset(dp,0,sizeof(dp));
    
    for(int i=0;i<N;i++){
      int v,w;
      scanf("%d,%d",&v,&w);
      for(int j=W;j>=0;j--){
	if(j+w <= W)dp[j+w] = max(dp[j+w], dp[j]+v);
      }
    }
    cout << "Case " << num++ << ":\n"; 
    cout << dp[W] << endl << (lower_bound(dp,dp+W+1,dp[W])-dp) << endl;
  }
}