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 <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctype.h>
#include <ctime>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <numeric>
#include <complex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

#define REP(i, x, n) for(int i = x; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define lengthof(x) (sizeof(x) / sizeof(*(x)))
#define FILL(ptr, value) FILL_((ptr), sizeof(ptr)/sizeof(value), (value))
template <typename T>
void FILL_(void * ptr, size_t size, T value){
  std::fill((T*)ptr, (T*)ptr+size, value);
}
//4方向ベクトル→↑←↓
int dx[] ={1,0,-1,0};
int dy[] ={0,-1,0,1};
int W;//風呂敷の容量
int N;//お宝の数
int dp[1010][1010];//dp[i][j]品物i番目までで重さがj以下の最大の価値
int dpW[1010][1010];
int Wt[1010];
int Vt[1010];
int ansW;
int main()
{
  int k = 1;
  while(cin>>W,W){
    cin >>N;
    for(int i = 1;i <=N;i++){
      int w,v;
      scanf("%d,%d",&v,&w);
      Vt[i] = v;
      Wt[i] = w;
    }
    for(int i = 0;i <=N;i++){
      for(int j = 0;j <=W;j++){
	dp[i][j] = 0;
      }
    }
    for(int i = 1;i <= N;i++){
      for(int j = 1;j <= W;j++){
	if(j-Wt[i]>=0){
	  if(dp[i][j] <dp[i-1][j-Wt[i]]+Vt[i]){
	    dp[i][j] =dp[i-1][j-Wt[i]]+Vt[i];
	  }else{
	    dp[i][j] =dp[i-1][j];
	  }
	}else{
	  dp[i][j] =dp[i-1][j];
	}
      }
  }
    ansW = 1;
    for(int j = 1;j <=W;j++){
      if(dp[N][ansW] <dp[N][j]){
	ansW =j;
      }
    }
    printf("Case %d:\n",k);
    k++;
    cout <<dp[N][W]<<endl;
    cout <<ansW<<endl;
  }
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std ;

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) (r).begin(),(r).end()
#define gsort(st,en) sort((st),(en),greater<int>())
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using dict = map<string,int>;
using pii = pair<int,int> ;

constexpr int imax = ((1<<30)-1)*2+1 ;
constexpr int inf = 100000000;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0};
const int dx[] = {0,-1,0,1};

inline bool value(int x,int y,int w,int h){
  return (x >= 0 && x < w && y >= 0 && y < h);
}

template<typename T>
void Unique(vector<T> &v){
  sort(all(v));
  v.erase(unique(all(v)),v.end());
}

template<typename T>
T ston(string& str, T n){
  istringstream sin(str) ;
  T num ;
  sin >> num ;
  return num ;
}

void Ans(bool f){
  if(f) cout << "YES"<<endl;
  else cout << "NO"<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  int w,n;
  int cnt = 1;
  char c;
  while(cin >> w){
    if(w == 0) break;
    cin >> n;
    vary(int,vs,n,0);
    vary(int,ws,n,0);
    vector<vector<pii>> dp(n+1,vector<pii>(w+1,make_pair(0,0)));
//     vector<vector<int>> dp2(n+1,vector<int>(w+1,0));
    rep(i,n){
      cin >> vs[i] >> c >> ws[i];
    }
    REP(i,0,n){
      rep(j,w+1){
        if(j <ws[i]){
          dp[i+1][j] = dp[i][j];
//           dp2[i+1][j] = dp2[i][j];
        }
        else{
          pii tmp;
          if(dp[i][j].fi < dp[i][j-ws[i]].fi+vs[i] && j != w){
            int k = dp[i][j-ws[i]].fi+vs[i];
            tmp = make_pair(k,j);
          }
          else{
            tmp = dp[i][j];
          }
          dp[i+1][j] = tmp;
//           dp2[i+1][j] = max(dp2[i][j],dp2[i][j-ws[i]]+vs[i]);
        }
      }
    }
    cout << "Case " + to_string(cnt) + ":"<<endl;
    cout << dp[n][w-1].fi <<endl;
    cout << dp[n][w-1].se <<endl;
    ++cnt;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

#define rep(i, n) for(int i = 0; i < n; i ++)
#define COUNT(i, n) for(int i = 1; i <= n; i ++)
#define ALL(T) T.begin(), T.end()
#define mp make_pair
#define pb push_back
#define ITER(c) __typeof((c).begin())
#define each(c, it) for(ITER(c) it = (c).begin(); it != (c).end(); it++)
#define X first
#define Y second

using namespace std;

typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<string> vs;

const int INF = 1 << 24;
const int N = 1001;

int dp[N];
int cnt;

int main(void){
    for(int ww; cin >> ww, ww;){
        int n; cin >> n;
        rep(i, N) dp[i] = -1;
        dp[0] = 0;
        while(n--){
            int p, w;
            char c; cin >> p >> c >> w;

            COUNT(i, N){
                int cur = N - i;
                if(~dp[cur] && cur + w <= ww) dp[cur + w] = max(dp[cur + w], dp[cur] + p);
            }
        }
        int ind = max_element(dp, dp + N) - dp;
        cout << "Case " << ++cnt << ":" << endl << dp[ind] << endl << ind << endl;
    }

    return 0;
}

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

int pri[1010],wai[1010],dp[2][1010];
int main(){
	int W,N,cas=0;
	while(true){
		cas++;
		cin>>W;
		if(W==0) break;
		cin>>N;
		for(int i=1;i<=N;i++){
			scanf("%d,%d",&pri[i],&wai[i]);
		}
		fill(dp[0],dp[0]+W+1,0);
		fill(dp[1],dp[1]+W+1,0);
		int in=0,ou=1;
		for(int i=1;i<=N;i++){
			fill(dp[ou],dp[ou]+W+1,0);
			for(int j=0;j<=W;j++){
				if(j+wai[i]<=W){
					dp[ou][j+wai[i]]=max(dp[ou][j+wai[i]],dp[in][j]+pri[i]);
				}
			}
			swap(in,ou);
		}
		int res=0,cnt=-1;
		for(int i=0;i<=W;i++){
			if(res<dp[in][i]){
				res=dp[in][i];
				cnt=i;
			}
		}
		cout<<"Case "<<cas<<":"<<endl<<res<<endl<<cnt<<endl;
	}
	return 0;
}