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 <stdio.h>
#include <vector>
#include <algorithm>

#define TEST 0
typedef std::pair<int,int> pi;//first: value,second: weight

struct Pred
{
    bool operator()(const pi& f,const pi& s)//<
    {
        return f.second < s.second;
    }
};

int wmax[1001],cnt[1000];
void maxassign(int index,int value)
{
    if(wmax[index] < value)
        wmax[index]=value;
}
pi rec_check(const std::vector<pi> &data,int start,int remw)
{
     
}
int main(void)
{
    int ccount=1;
    int w,n;
    using namespace std;
    vector<pair<int,int> > data;
    while(scanf("%d%d",&w,&n)==2 && w!=0)
    {
        data.assign(n,std::pair<int,int>(0,0));
        for(int i=0;i<n;i++)
        {
            scanf("%d%*[,]%d",&data[i].first ,&data[i].second );
        }
        Pred pred;
        sort(data.begin(),data.end(),pred);
        printf("Case %d:\n",ccount);
        for(int i=0;i<1001;i++)
        {
            wmax[i]=-1;
        }
        wmax[0]=0;
#if TEST
        for(int i=0;i<n;i++)
        {
            printf("val=%d,wei=%d\n",data[i].first,data[i].second);
        }
#endif
        for(int i=0;i<n;i++)
        {
            //Now we think about treasure[i]
            for(int j=w-data[i].second;j>=0;j--)
            {
                if(wmax[j] != -1)
                    maxassign(j+data[i].second,wmax[j]+data[i].first);
            }
        }
        int max=-1;
        int ind=-1;
        for(int i=0;i<=w;i++)
        {
            if(max < wmax[i])
            {
                max=wmax[i];
                ind=i;
            }
        }
#if TEST
        for(int i=0;i<=w;i++)
        {
            if(wmax[i] != -1)
                printf("\nwmax[%d]=%d",i,wmax[i]);
        }
#endif
        printf("%d\n%d\n",max,ind);
        data.clear();
        ccount++;
    }
    return 0;
}

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){
	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)rep(j,W)dp[j][i] = -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>
using namespace std;

int dp[1001][1000];
int main(){
	int w, cntcase = 1;
	while (cin >> w, w){
		int n, treas_val[1000], treas_w[1000], ans_val = 0, ans_w = 0;
		cin >> n;
		for (int i = 0; i <= n; i++)for (int j = 0; j < w; j++) dp[i][j] = -1;
		dp[0][0] = 0;
		for (int i = 0; i < n; i++){
			scanf("%d,%d", &treas_val[i], &treas_w[i]);
		}
		for (int i = 0; i < n; i++){
			for (int j = 0; j < w; j++){
				if (dp[i][j] != -1){
					if (j + treas_w[i] < w
						&& dp[i + 1][j + treas_w[i]] < dp[i][j] + treas_val[i])
						dp[i + 1][j + treas_w[i]] = dp[i][j] + treas_val[i];
					if (dp[i][j] > dp[i + 1][j])
						dp[i + 1][j] = dp[i][j];
				}
				//printf("%d ", dp[i][j]);
			}
			//puts("");
		}
		for (int i = 0; i < w; i++){
			if (ans_val < dp[n][i]){
				ans_val = dp[n][i];
				ans_w = i;
			}
		}
		printf("Case %d:\n%d\n%d\n", cntcase, ans_val, ans_w);
		cntcase++;
	}
	return 0;
}

C++: #include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) { ostringstream sout; sout << x; return sout.str();}
typedef vector<int> vi;
typedef vector<vi>  vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX/10;

int main() {
	int W, N, count = 0;

	while(cin >> W, W) {
		count++;
		cin >> N;
		vvi data(N, vi(2));
		char c;
		REP(i, N) {
			cin >> data[i][0] >> c >> data[i][1];
		}

		vvi dp(N+1, vi(W+1));
		REP(j, W+1) {
			dp[0][j] = 0;
		}

		REP(i, N) {
			FOR(j, 0, W) {
				if(j < data[i][1]) {
					dp[i+1][j] = dp[i][j];
				} else {
					dp[i+1][j] = max(dp[i][j], dp[i][j-data[i][1]]+data[i][0]);
				}
			}
		}

		int ans_w = 0, ans_j;
		FOR(j, 0, W) {
			if(ans_w < dp[N][j]) {
				ans_w = dp[N][j];
				ans_j = j;
			}
		}

		cout << "Case " << count << ":" << endl;
		cout << ans_w << endl;
		cout << ans_j << endl;
	}

	return 0;
}