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 <iostream>
#include <stdio.h>
#include <string>
using namespace std;


int main() {
  int dp[2][1001],n,k[1000],w[1000],i,j,h,kg,mk,mw,cn=0;
  while(true) {
	  cin >> kg;
	  if (kg==0) break;
	  for (i=0;i<=kg;i++) {dp[0][i]=0; dp[1][i]=0;}
	  cin >> n;
	  for (i=0;i<n;i++) scanf("%d,%d",&k[i],&w[i]);
	  for (i=0,j=0;i<n;i++) {
		  j=1-j;
		  for (h=kg;h>=0;h--)
			  if (h+w[i]>kg) dp[j][h]=dp[1-j][h];
			  else dp[j][h]=(dp[1-j][h+w[i]]+k[i])>dp[1-j][h] ? dp[1-j][h+w[i]]+k[i] : dp[1-j][h];
	  }
  mk=0;
  for (i=kg;i>=0;i--) if (mk<dp[j][i]) {mk=dp[j][i]; mw=i;}
  cn++;
  cout << "Case " << cn << ":" << endl;
  cout << mk << endl;
  cout << kg-mw << endl;
  }
 
  return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <ctime>
using namespace std;

#define rep(i,a,n) for(int i=a; i<n; i++)
#define repr(i,a,n) for(int i=a; i>=n; i--)
#define pb(a) push_back(a)
#define fr first
#define sc second
#define INF 999999999

#define X real()
#define Y imag()
#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) ( EQ((a).X, (b).X) && EQ((a).Y, (b).Y) )
#define LE(n, m) ((n) < (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))

typedef vector<int> VI;
typedef vector<VI> MAT;
typedef pair<int, int> pii;
typedef long long int ll;

typedef complex<double> P;
typedef pair<P, P> L;
typedef pair<P, double> C;

namespace std {
    bool operator<(const P a, const P b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

int const MOD = 1000000007;

int main() {
    int W,N;
    int c = 0;
    while(cin >> W) {
        if(W == 0) break;
        c++;
        cin >> N;
        int v[1010], w[1010];

        rep(i,0,N) scanf("%d,%d",&v[i], &w[i]);
        int dp[1010][1010];
        rep(j,0,W+1) dp[0][j] = 0;
        rep(i,0,N) {
            rep(j,0,W+1) {
                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]);
            }
        }

        int a = 0, b = 0;
        rep(i,0,W+1) {
            if(dp[N][i] > a) {
                a = dp[N][i];
                b = i;
            }
        }

        printf("Case %d:\n", c);
        cout << a << endl;
        cout << b << endl;
    }

    return 0;
}

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

struct Item {
  int value;
  int weight;
};

int main () {
  for( int case_n = 1; ; case_n++  ) {
    int w, n;
    vector< Item >items;
    vector< vector<int> >dp;
    vector< vector<int> >dpw;
    cin >> w;
    if( !w ) { return EXIT_SUCCESS; }
    cin >> n;
    
    for( int i = 0; i < n; i++ ) {
      string line;
      cin >> line;
      replace( line.begin(), line.end(), ',', ' ' );
      istringstream iss( line );
      
      Item item;
      iss >> item.value >> item.weight;
      items.push_back( item );
    }
    for( int i = 0; i <= n; i++ ) {
      vector<int> dpline;
      vector<int> dpwline;
      for( int j = 0; j <= w; j++ ) {
        int opt, optw;
        if( i == 0 || j == 0 ) {
          opt = 0;
          optw = 0;
        } else if( j < items[ i - 1 ].weight ) {
          opt = dp[ i - 1 ][ j - 1 ];
          optw = dpwline[ j - 1 ];
        } else { 
          if( 
            dp[ i - 1 ][ j - 1 ] <
            dp[ i - 1 ][ j - items[ i - 1 ].weight ] + items[ i - 1 ].value
          ) {
            opt  =  dp[ i - 1 ][ j - items[ i - 1 ].weight ] + items[ i - 1 ].value;
            optw = dpw[ i - 1 ][ j - items[ i - 1 ].weight ] + items[ i - 1 ].weight;
          } else if(
            dp[ i - 1 ][ j - 1 ] ==
            dp[ i - 1 ][ j - items[ i - 1 ].weight ] + items[ i - 1 ].value
          ) {
            opt  =  dp[ i - 1 ][ j - items[ i - 1 ].weight ] + items[ i - 1 ].value;
            optw = min(
              dpwline[ j - 1 ],
              dpw[ i - 1 ][ j  - items[ i - 1 ].weight ] + items[ i - 1 ].weight
            );
          } else {
            opt = dp[ i - 1 ][ j - 1 ];
            optw = dpwline[ j - 1 ];
          }
        }
        dpline.push_back( opt );
        dpwline.push_back( optw );
      }
      dp.push_back( dpline );
      dpw.push_back( dpwline );
    }
    cout << "Case " << case_n << ":"<<endl;
    cout << dp[ n ][ w ] << endl;
    cout << dpw[ n ][ w ] << endl;
  }
  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;
	}
	if(dp[weight][index+1]<value)dfs(weight, value, index+1);
	if(weight+weig[index] > W && dp[weight+weig[index]][index+1]<value+tres[index])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();
}