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>
using namespace std;
main(){
  int b,c,N,K[1010],P[1010],i,m,j,W,dp[1010],h=1,y,g;
  char d;
  while(1){
    y=0;
    b=0;
    cin >> W;
    for(i=0;i<=W;i++){
      dp[i]=0;
    }
    if(W==0){
      break;
    }
    cin >> N;
    for(i=0;i<N;i++){
      cin >> P[i] >> d >> K[i];
      c=K[i];
      if(K[i]<W){
      dp[K[i]]=P[i];
      for(j=W;j>=0;j--){
	if(dp[j]!=0){
	  if(dp[c+j]!=0){
	    if(dp[c+j]<dp[c]+dp[j]){
	      dp[c+j]=dp[c]+dp[j];
	    }
	    else{
	      continue;
	    }
	  }
	  if(dp[c+j]==0){
	    dp[c+j]=dp[c]+dp[j];
	  }
	}
      }
    }
    }
    for(i=1;i<=W;i++){
      if(dp[i]>b){
	y=i;
	b=dp[i];
      }
      else{
	continue;
      }
    }
    cout << "Case:" << " " << h << endl;
    cout << b << endl << y << endl;
    h++;
  }
}

C++: #include<iostream>
#include<string.h>
#include<vector>
#include<list>
#include<stdio.h>
#include<math.h>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) range(i,0,b)
#define debug(x) cout << "debug " << x << endl;
using namespace std;

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

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

const int MAX_N = 1000;
const int MAX_W = 1000;
int W, N;
int v[MAX_N];
int w[MAX_N];
int dp[MAX_W + 1];

void solve() {
	fill(dp, dp + W + 1, 0);
	for (int i = 0; i < N; i++) {
		for (int j = W; j >= 0; j--) {
			if (j + w[i] <= W) {
				dp[j + w[i]] = max(dp[j + w[i]], dp[j] + v[i]);
			}
		}
	}
	printf("%d\n", dp[W]);
	for (int i = W; i >= 0; i--) {
		if (dp[W] != dp[i]) {
			printf("%d\n", i + 1);
			break;
		}
	}
}

int main () {
	int i = 0;
	while (scanf("%d", &W), W) {
		i++; printf("Case %d:\n", i);
		scanf("%d", &N);
		for (int i = 0; i < N; i++) {
			scanf("%d,%d", &v[i], &w[i]);
		}
		solve();
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>

using namespace std;

typedef pair<int, int> obj;

int main(){
  int N, W, weight, value;
  char ch;
  int case_num = 1;

  while(1){
    cin >> W;
    if(W == 0) break;
    cin >> N;

    vector<obj> obj_list;
    int dp[1010];
    memset(dp, -1, sizeof(dp));
    
    for(int i = 0; i < N; i++){
      cin >> value >> ch >> weight;
      obj_list.push_back(obj(value, weight));
    }

    dp[0] = 0;

    for(int i = 0; i < N; i++){
      obj o = obj_list[i];

      for(int j = W - o.second; j >= 0; j--){
        if(dp[j] != -1){
          dp[j+o.second] = max(dp[j+o.second], dp[j] + o.first);
        }
      }
    }
    int answer = 0;
    int answer_weight = 0;

    for(int i = 0; i <= W; i++){
      if(answer < dp[i]){
        answer = dp[i];
        answer_weight = i;
      }
    }

    cout << "Case " << case_num << ":" << endl;
    cout << answer << endl;
    cout << answer_weight << endl;

    case_num++;
  }

  return 0;
}

C++: #include <stdio.h>
#include <algorithm>
using namespace std;
int W, N, v[1000], w[1000], dp[1001][1001], c, r;
int main() {
	while (~scanf("%d", &W)) {
		if (!W) break;
		scanf("%d", &N);
		for (int i = 0; i < N; i++) scanf("%d,%d", &w[i], &v[i]);
		for (int i = 1; i <= N; i++) {
			for (int j = 0; j <= W; j++) {
				dp[i][j] = dp[i - 1][j];
				if (j >= w[i - 1]) {
					dp[i][j] = max(dp[i][j], dp[i - 1][j - w[i - 1]] + v[i - 1]);
				}
			}
		}
		printf("Case %d:\n", ++c);
		printf("%d\n", dp[N][W]);
		printf("%d\n", lower_bound(dp[N], dp[N] + W + 1, dp[N][W]) - dp[N]);
	}
	return 0;
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
#define SIZE(x) ((int)(x).size())
#define UQ(v) v.erase(unique(v,begin(),v,end()),v.end());
#define INF 11922960 
#define pb push_back 
int dxy4[5] = { 0,1,0,-1,0 };
int dxy8[9] = { 0,1,1,0,-1,1,-1,-1,0 };
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
#define all(x) (x).begin(),(x).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)




//vector< vector<int> > v (max1, vector<int>(max2) );
int main() {
	int n, W, count = 0;
	while (1) {
		count++;
		cin >> W >> n;
		if (!W) break;
		vector<vector<int>>dp(n+1000, vector<int>(W+10, 0));
		vector<int> v(n + 1, 0);
		vector<int> w(n + 1, 0);


		 char s;
		rep(i, n) { cin >> v[i+1]>> s>>w[i+1]; }

		rep(i, (n+1)) {
			if (!i)continue;
			//cout << i << "-------" << endl;
			rep(j, W-w[i]+1) {
				dp[i][w[i] + j] = max({ dp[i - 1][w[i] + j], dp[i - 1][j] + v[i]});
				//cout << dp[i][w[i]+j] << " ";
			}
			//cout << endl;
		}
		int umax = dp[n][W];
		rep(i, W + 1) {
			if (dp[n][i] == umax) {
				cout << "Case " << count <<":"<< endl<< umax << endl << i << endl;
				break;
			}
		}
	}
int jk;
cin >> jk;
	return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;

int main(){
   int n,W;
   int w[1000],v[1000];
   int i,l,z,count=1,Max;
   int dp[2][1001];
   string Case = "Case ";
   char s;
   
   for(;;){
      cin>>W;
      if(W==0) break;
      
      cin>>n;
      for(i=0;i<n;i++) cin>>v[i]>>s>>w[i];
      
      memset(dp,0,sizeof(dp));
      Max=0;
      
      for(i=1;i<=n;i++){
         for(l=1;l<=W;l++){
            if(w[i]>l)
               dp[1][l] = dp[0][l];
            else{
               dp[1][l] = max(dp[0][l],dp[0][l-w[i]]+v[i]);
            }
         }
         for(z=0;z<=W;z++) dp[0][z]=dp[1][z];
         
         memset(dp[1],0,sizeof(dp[1]));
      }
      for(i=W-1;i>=0;i--){
         if(dp[0][i+1]==dp[0][i])
            continue;
         else{
            Max=i+1;
            break;
         }
      }
      
      cout<<Case<<count<<":"<<endl;
      cout<<dp[0][W]<<endl;
      cout<<Max<<endl;
      count++;
   }
   return 0;
}