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(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 && 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;
		}

		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<map>
#include<set>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<complex>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<numeric>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cctype>

#define mp make_pair
#define pb push_back
#define REP(i,a,n) for(int i = a;i < (n);i++)
#define rep(i,n) for(int i = 0;i < (n);i++)
#define all(s) s.begin(), s.end()
#define rall(s) s.rbegin(), s.rend()

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<vector<int> > VII;
typedef pair<int,int> PII;

const int DX[]={1,0,-1,0},DY[]={0,-1,0,1};

int main(){
	cin.tie(0);
   	ios::sync_with_stdio(false);
	int w,n,index = 1;
	
	while(1){
		int ans_v = 0,ans_w = 0;
		VI value,weight;

		cin >> w;
		if(w == 0) break;
		cin >> n;

		VII dp(n + 1,VI (w + 1,-1));
		dp[0][0] = 0;

		rep(i,n){
			int a,b;
			char ch;
			cin >> a >> ch >> b;
			value.pb(a);
			weight.pb(b);
		}

		rep(i,n){
			rep(j,w + 1){
				if(dp[i][j] == -1) continue;
				dp[i + 1][j] = max(dp[i + 1][j],dp[i][j]); //valle[i]テ」ツつ津ィツカツウテ」ツ?陛」ツ?ェテ」ツ??・ツ?エテ・ツ青?
				if(j + weight[i] <= w){ //value[i]テ」ツつ津ィツカツウテ」ツ?凖・ツ?エテ・ツ青?
					dp[i + 1][j + weight[i]] = max(dp[i + 1][j + weight[i]],value[i] + dp[i][j]);
					
				}
			}
		}

		rep(i,dp[n].size()){
			if(dp[n][i] > ans_v){
				ans_v = dp[n][i];
				ans_w = i;
			}
		}		

		cout << "Case " << index++ << ':' << endl;
		cout << ans_v << endl << ans_w << endl;
	}

	return 0;
}

C++: #include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(void){
    for(int x=1;;x++){
        int l;
        int n;
        int v[1010]={0};
        int w[1010]={0};
        int dp[10][1010]={0};
        int we[10][1010]={0};
        cin >> l;
        if(l==0)break;
        cin >> n;
        for(int i=1;i <= n;i++){
            scanf("%d,%d",&v[i],&w[i]);
        }
        for(int i=1;i <= n;i++){
            for(int j=0;j <= l;j++){
                if(j < w[i]){
                    dp[2][j] = dp[1][j];
                    we[2][j] = we[1][j];
                }
                else{
                    if(dp[1][j]>dp[1][ j-w[i] ] + v[i]){
                        dp[2][j] = dp[1][j];
                        we[2][j] = we[1][j];
                    }
                    else{
                        dp[2][j] = dp[1][ j-w[i] ] + v[i];
                        we[2][j] = we[1][ j-w[i] ]+w[i];
                    }
                }
            }
            /*for(int k=0;k<=l;k++)cout<<we[i+1][k]<<" ";
            cout<<endl;*/
            for(int k=0;k <= l;k++){
                dp[1][k] = dp[2][k];
                we[1][k] = we[2][k];
            }
        }
        /*for(int i=1;i<=n;i++){
            for(int j=0;j<=l;j++){
            cout<<dp[i][j]<<" ";
            }
            cout<<endl;
        }*/
        cout<<"Case "<<x<<":"<<endl;
        cout<<dp[2][l]<<endl;
        cout<<we[2][l]<<endl;

    }
	return 0;
}

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

int main()
{
  int cnt = 0, W, N;
  static int v[1000], w[1000], dp[1000+1][1000+1];
  while (~scanf("%d\n", &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", &N);
    for (int i = 0; i < N; ++i)
      scanf("%d,%d\n", &v[i], &w[i]);

    int maxV = -1, minW = 1 << 30;
    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]);
	if (maxV < dp[i+1][j]) {
	  maxV = dp[i+1][j];
	  minW = j;
	} else if (maxV == dp[i+1][j]) {
	  minW = min(minW, j);
	}
      }
    }

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