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 <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <istream>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <climits>
using namespace std;
 
typedef ostringstream OSS;
typedef istringstream ISS;
 
typedef vector<int> VI;
typedef vector< VI > VVI;
 
typedef long long LL;
 
typedef pair<int, int> PII;
typedef vector<PII> VPII;
 
#define X first
#define Y second
 
int main(void) {
	int dataset_index = 1;

	int W, N;
	while (cin >> W >> N, W) {
		VI ps(N), ws(N);

		char dummy;
		for (int i = 0; i < N; i++) {
			cin >> ps[i] >> dummy >> ws[i];
		}

		VVI dp(N + 1, VI(W + 1, -1));
		dp[0][0] = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < W + 1; j++) {
				if (dp[i][j] == -1) continue;
				
				dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]);

				int w = j + ws[i];
				int p = dp[i][j] + ps[i];
				if (w <= W) {
					dp[i + 1][w] = max(dp[i + 1][w], p);
				}
			}
		}

		int ans_p = 0, ans_w = 0;

		for (int i = 0; i < W + 1; i++) {
			if (dp[N][i] > ans_p) {
				ans_p = dp[N][i];
				ans_w = i;
			}
		}

		cout << "Case " << dataset_index << ":" << endl;
		cout << ans_p << endl << ans_w << endl;

		++dataset_index;
	}
}

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

using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef pair<int, int> PII;

#define FOR(i, a, n) for (int i = (int)a; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define MOD 1000000007
#define INF 1000000000
#define PI 3.14159265359
#define EPS 1e-12

int W, N, v[1010], w[1010], dp[1010];

int main(void) {
  int ca = 1;
  while (true) {
    cin >> W;
    if(W == 0) break;
    cin >> N;
    REP(i, N) {
      cin >> v[i];
      getchar();
      cin >> w[i];
    }
    REP(i, W+5) dp[i] = 0; 

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

    int a = -INF, b = 0;
    for (int i = 0; i < W+1; i++) {
      //cout << dp[i] << " ";
      if (a < dp[i]) {
        a = dp[i];
        b = i;
      }
    }
    //cout << endl;
    cout << "Case " << ca << ":" << endl << a << endl << b << endl;
    ca++;
  }
  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){
			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){
			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>

using namespace std;

int dp[1001][1001] = {0};
int main() {
	int W, N;
	int t = 1;
	while ( cin >> W, W ) {
		cin >> N;
		vector<int> v(N), w(N);
		for (int i = 0; i < N; ++i) {
			scanf("%d,%d", &v[i], &w[i]);
		}
		fill(&dp[0][0], &dp[0][0]+1001*1001, 0);
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < W; ++j) {
				if (w[i] + j < W) {
					dp[i+1][w[i] + j] = max(dp[i+1][w[i] + j], dp[i][j] + v[i]);
				}
				dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
			}
		}
		int aw = 0, av = 0;
		for (int i = 0; i < W; ++i) {
			if (dp[N][i] > av) {
				av = dp[N][i], aw = i;
			}
		}
		cout << "Case " << t << ":" << endl;
		cout << av << endl;
		cout << aw << endl;
		++t;
	}
}

C++: #include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int dp[10000][10000];

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

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

long long dp[1000];
int main(){
	long long w, n, ans_w = 0, ans_val = 0;
	for (int dataset = 1; cin >> w, w; dataset++){
		long long t_w, t_val;
		cin >> n;
		for (long long i = 0; i <= w; i++) dp[i] = -1;
		dp[0] = 0;
		for (long long i = 0; i < n; i++){
			scanf("%lld,%lld", &t_val, &t_w);
			for (long long j = w; j >= 0; j--){
				//printf("%d ", dp[j]);
				if (dp[j] == -1 || j + t_w > w || dp[j + t_w] > dp[j] + t_val)
					continue;
				dp[j + t_w] = dp[j] + t_val;
			}
			//puts("");
		}
		for (long long i = 0; i <= w; i++){
			//printf("%d ", dp[i]);
			if (ans_val < dp[i]){
				ans_val = dp[i];
				ans_w = i;
			}
		}
		//puts("");
		printf("Case %d:\n%lld\n%lld\n", dataset, ans_val, ans_w);
	}
	return 0;
}