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>
#define MAX_N 1000
#define MAX_W 1000
using namespace std;
int dp[MAX_N+1][MAX_W+1];
int N,W;
int v[MAX_N+1],w[MAX_N+1];

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

int main() {
  int vt,wt,p=0,minW;
  while(cin >> W) {
    if(W==0)break;
    cin >> N;
    for(int i=1;i<=N;i++) {
      scanf("%d,%d",&vt,&wt);
      v[i] = vt; w[i] = wt;
    }
    solve();
    p++;
    printf("Case %d:\n",p);
    int top = dp[N][W];
    for(int i=0;i<W;i++) {
      if(top == dp[N][W-i]) {
        minW = W-i;
        continue;
      }
      break;
    }
    printf("%d\n%d\n",dp[N][W],minW);
  }
}

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(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;
	}
	dfs(weight, value, index+1);
	dfs(weight+weig[index], value+tres[index], index+1);
}


int main(void){
	ios::sync_with_stdio(false);
    cin.tie(0);
	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;
		}

		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 <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

#define MAX_W 1000
#define MAX_N 10000
typedef vector<pair<int, int> > vec;

int main(){
	int W, N, c = 1;
	while( cin >> W, W ){
		cin >> N;
		vector<vec> dp(N+1, vec(W+1));
		vector<int> w(N), v(N);
		for( int i = 0; i < N; i++ ){
			scanf("%d,%d", &v[i], &w[i]);
		}
		dp[0][0] = make_pair(0, 0);
		for( int i = 0; i < N; i++ ){
			for( int j = 0; j <= W; j++ ){
				if( j-w[i] >= 0 ){
					if( dp[i][j].first < dp[i][j-w[i]].first+v[i] ){
						dp[i+1][j].first = dp[i][j-w[i]].first+v[i];
						dp[i+1][j].second = dp[i][j-w[i]].second+w[i];
					}else if( dp[i][j].first == dp[i][j-w[i]].first+v[i] ){
						if( dp[i][j].second < dp[i][j-w[i]].second+w[i] ){
							dp[i+1][j].first = dp[i][j].first;
							dp[i+1][j].second = dp[i][j].second;
						}else{
							dp[i+1][j].first = dp[i][j-w[i]].first+v[i];
							dp[i+1][j].second = dp[i][j-w[i]].second+w[i];
						}
					}else{
						dp[i+1][j].first = dp[i][j].first;
						dp[i+1][j].second = dp[i][j].second;
					}
				}else{
					dp[i+1][j] = make_pair(dp[i][j].first, dp[i][j].second);
				}
			}
		}
		/*for( int i = 0; i <= N; i++ ){
			printf("%d: ", i);
			for( int j = 0; j <= W; j++ ){
				printf("%d ", dp[i][j].second);
			}
			printf("\n");
		}*/
		printf("Case %d:\n%d\n%d\n", c, dp[N][W].first, dp[N][W].second);
		c++;
	}
}

C++: #include <bits/stdc++.h>

using namespace std;

#define FOR(i, j, k) for(int i = j; i < k; ++i)
#define rep(i, j) FOR(i, 0, j)
#define Rrep(i, j) for(int i = j; i >= 0; --i)
#define INF (1 << 30)

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;

int dp[1001][1001];
int v[1000], w[1000];

int main() {
	int W, N;
	int c = 1;
	while(1) {
		scanf("%d", &W);
		if(W == 0) break;
		memset(dp, 0, sizeof(dp));
		scanf("%d", &N);
		int wans = 0;
		rep(i, N) scanf("%d,%d", &v[i], &w[i]);
		rep(i, N) rep(j, W + 1) {
			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]);
			}
		}
		Rrep(i, W) if(dp[N][i] != dp[N][W]){
			printf("Case %d :\n", c++);
			printf("%d\n", dp[N][W]);
			printf("%d\n", i + 1);
			break;
		}
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<string>

using namespace std;

#define reps(i,f,n) for(int i=f;i<int(n);i++)
#define rep(i,n) reps(i,0,n)

int w,n;
vector<int> v;
vector<int> g;

void init(){
	v.clear();
	g.clear();
}
bool input(){
	cin>>w;
	if(w==0)return false;
	cin>>n;
	
	rep(i,n){
		int a,b;
		scanf("%d,%d",&a,&b);
		v.push_back(a);
		g.push_back(b);
	}
	return true;
}

const int W = 1111;
const int N = 1111;
const int INF = 1000000000;
int dp[N][W];

pair<int,int> solve(){
	rep(i,N)rep(j,W)dp[i][j]=0;
	
	dp[0][0] = 0;
	dp[0][g[0]] = v[0];
	
	reps(i,1,n){
		rep(j,w){
			dp[i][j] = dp[i-1][j];
			if(j-g[i]>=0)dp[i][j] = max(dp[i][j], dp[i-1][j-g[i]]+v[i]);
		}
	}
	
	int maxp = 0;
	rep(j,w){
		if(dp[n-1][maxp]<dp[n-1][j])maxp=j;
	}
	
	/*
	rep(i,n){
		rep(j,w)printf("%3d ",dp[i][j]);puts("");
	}*/
	
	return pair<int,int>(dp[n-1][maxp],maxp);
}
int main(){
	for(int i=1;init,input();i++){
		pair<int,int> ans = solve();
		printf("Case %d:\n%d\n%d\n",i,ans.first,ans.second);
	}
}

/*
10
5
60,2
100,4
120,6
210,9
10,1
0

*/