Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	Case := 1
	for {
		scanner.Scan()
		W, _ := strconv.Atoi(scanner.Text())
		if W == 0 {
			break
		}
		scanner.Scan()
		n, _ := strconv.Atoi(scanner.Text())
		w := make([]int, n+1)
		v := make([]int, n+1)
		for i := 1; i <= n; i++ {
			scanner.Scan()
			info := strings.Split(scanner.Text(), ",")
			v[i], _ = strconv.Atoi(info[0])
			w[i], _ = strconv.Atoi(info[1])
		}
		// fmt.Println(v)
		// fmt.Println(w)
		dp := make([][]int, n+1)
		for i := range dp {
			dp[i] = make([]int, W+1)
		}
		maxV := -(1 << 21)
		minW := 1 << 21
		for i := 1; i <= n; i++ {
			for j := 1; j <= W; j++ {
				// fmt.Println(dp)
				if j-w[i] >= 0 {
					dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i])
					if maxV < dp[i][j] {
						maxV = dp[i][j]
						minW = j
					} else if maxV == dp[i][j] {
						minW = min(minW, j)
					}
				} else {
					dp[i][j] = dp[i-1][j]
				}
			}
		}
		fmt.Printf("Case %d:\n", Case)
		Case += 1
		fmt.Println(maxV)
		fmt.Println(minW)
	}
}
func max(x, y int) int {
	if x < y {
		return y
	}
	return x
}
func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

C++: #include <iostream>
#include <algorithm>
#include <utility>
#include <string>
#include <sstream>
using namespace std;

const int W_MAX = 1000;
const int N_MAX = 1000;

int v[N_MAX + 1], w[N_MAX + 1];
int N,W;


typedef pair<int,int> P;

P bfs(int i, int j)
{
	if(i == N)return P(0,0);
	if(w[i] > j){
		return bfs(i+1,j);
	}
	else{
		P p1,p2;
		p1 = bfs(i + 1,j);
		p2 = bfs(i + 1,j - w[i]);
		p2.first += v[i];p2.second += w[i];
		if(p1.first == p2.first){
			if(p1.second < p2.second){
				return p1;
			}
			else{
				return p2;
			}
		}
		else{
			return max(p1,p2);
		}
	}
}

int main()
{
	int c = 1;
	while(cin >> W,W){
		cin >> N;
		for(int i = 0; i < N; ++i){
			cin >> v[i]; cin.ignore(1,','); cin >> w[i];
		}
		cout << "Case " << c++ << ':' << endl;
		P p = bfs(0,W);
		cout << p.first << endl << p.second << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int main() {
    int W;
    int c = 0;
    while(++c, cin >> W, W) {
        int N;
        cin >> N;
        vector<vector<int>> dp(N+1, vector<int>(W+1, -1));
        dp[0][0] = 0;
        for(int i=0; i<N; ++i) {
            int v, w;
            scanf("%d,%d", &v, &w);
            for(int j=0; j<=W; ++j) {
                dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
                if(j+w <= W && dp[i][j] != -1) {
                    dp[i+1][j+w] = max(dp[i+1][j+w], dp[i][j] + v);
                }
            }
        }
        int w = 0;
        for(int i=0; i<=W; ++i) {
            if(dp[N][w] < dp[N][i]) {
                w = i;
            }
        }
        cout << "Case " << c << ':' << endl;
        cout << dp[N][w] << endl;
        cout << w << endl;
    }
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <cstdio>
 
using namespace std;
 
int W , N ;
int dp[1024][1024];
int w[1024] , v[1024],O;
char cn;

int main ()
{
  int cont = 1;
  while(cin >> W >> N){
    
    for(int i = 0; i < N; i++)
      cin >> v[i] >> cn >> w[i] ;
    
    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] );
	  }
      }
    for(int i = 0; i <=W; i++)
      if(dp[0][i]==dp[0][W]){
	O = i;
	break;
      }
    cout << "Case " << cont <<':' <<endl;
    cout << dp[0][W] << endl << O <<endl;
    //cout << << endl;
    /*  
    for(int i = 0; i < 10 ; i++)
      {       
	for(int j = 0; j <= 50; j++)
	  printf("%3d", dp[i][j]);
        puts("");
      }    
      }*/
    cont++;
  }
}

C++: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
//#define int long long
using namespace std;

int W, N;
int v[1000], w[1000];
pair<int, int> dp[1100][1100];

pair<int, int> rec(int i, int j)
{
	pair<int, int> ans;

	if (dp[i][j].first != -1 && dp[i][j].second != -1)
	{
		return dp[i][j];
	}

	if (i == N)
	{
		ans = pair<int, int>(0, W - j);
	}
	else if (j < w[i])
	{
		ans = rec(i + 1, j);
	}
	else
	{
		pair<int, int> vw1 = rec(i + 1, j);
		pair<int, int> vw2 = rec(i + 1, j - w[i]);
		vw2.first += v[i];
		if (vw1.first > vw2.first)
		{
			ans = vw1;
		}
		else if (vw1.first < vw2.first)
		{
			ans = vw2;
		}
		else if (vw1.first == vw2.first)
		{
			if (vw1.second < vw2.second)
			{
				ans = vw1;
			}
			else
			{
				ans = vw2;
			}
		}
	}

	dp[i][j] = ans;

	return ans;
}

signed main()
{
	int cnt = 1;

	while (true)
	{
		cin >> W;
		if (W == 0)
		{
			break;
		}
		cin >> N;
		rep(i,N)
		{
			scanf("%d,%d", &v[i], &w[i]);
		}

		rep(i,1100)
		{
			rep(j,1100)
			{
				dp[i][j] = pair<int, int>(-1, -1);
			}
		}

		pair<int, int> ans = rec(0, W);

		printf("Case %d:\n", cnt);
		printf("%d\n", ans.first);
		printf("%d\n", ans.second);

		cnt++;
	}
}

C++: #include <cstdio>

using namespace std;

void rec(int n, int w, int &v, int &rw,
        const int W, const int N,
        const int lv[], const int lw[])
{
    v = rw = 0;
    if (n == N) {
        // not remain any treasure
        v = 0;
        rw = w;
    } else if (w < lw[n]) {
        // cannot pack treasure[n]
        rec(n + 1, w, v, rw, W, N, lv, lw);
    } else {
        int v1, v2, w1, w2;

        // through treasure[n]
        rec(n + 1, w        , v, rw, W, N, lv, lw);
        v1 = v;
        w1 = rw;
        // pack treasure[n]
        rec(n + 1, w - lw[n], v, rw, W, N, lv, lw);
        v2 = v + lv[n];
        w2 = rw - lw[n];

        // which is good
        if (v1 > v2) {
            v = v1;
            rw = w1;
        } else if (v1 < v2) {
            v = v2;
            rw = w2;
        } else {
            if (w1 >= w2) {
                v = v1;
                rw = w1;
            } else {
                v = v2;
                rw = w2;
            }
        }
    }
    // printf("  (%d, %d, %d, %d) -> (%d, %d)\n", n, w, v, rw, v, rw);
}

int dp_v[1000][1000];
int dp_rw[1000][1000];

void rec_dp(int n, int w, int &v, int &rw,
        const int W, const int N,
        const int lv[], const int lw[])
{
    // memo'd
    if (dp_v[n][w] != -1 && dp_rw[n][w] != -1) {
        v = dp_v[n][w];
        rw = dp_rw[n][w];
        return;
    }

    v = rw = 0;
    if (n == N) {
        // not remain any treasure
        v = 0;
        rw = w;
    } else if (w < lw[n]) {
        // cannot pack treasure[n]
        rec_dp(n + 1, w, v, rw, W, N, lv, lw);
    } else {
        int v1, v2, w1, w2;

        // through treasure[n]
        rec_dp(n + 1, w        , v, rw, W, N, lv, lw);
        v1 = v;
        w1 = rw;
        // pack treasure[n]
        rec_dp(n + 1, w - lw[n], v, rw, W, N, lv, lw);
        v2 = v + lv[n];
        w2 = rw;

        // which is good
        if (v1 > v2) {
            v = v1;
            rw = w1;
        } else if (v1 < v2) {
            v = v2;
            rw = w2;
        } else {
            if (w1 >= w2) {
                v = v1;
                rw = w1;
            } else {
                v = v2;
                rw = w2;
            }
        }
    }
    // printf("  (%d, %d, %d, %d) -> (%d, %d)\n", n, w, v, rw, v, rw);
    dp_v[n][w] = v;
    dp_rw[n][w] = rw;
}

int main()
{
    for (int icase = 1;; ++icase) {
        int W, N;
        scanf("%d", &W);
        if (W == 0)
            break;
        scanf("%d", &N);

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

        int retv, retw;
        for (int i = 0; i < 1000; ++i)
            for (int j = 0; j < 1000; ++j)
                dp_v[i][j] = dp_rw[i][j] = -1;
        rec_dp(0, W, retv, retw, W, N, v, w);

        printf("Case %d:\n%d\n%d\n", icase, retv, W - retw);
    }

    return 0;
}