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
}

Python: c=0
for W in iter(input,'0'):
 c+=1
 W=int(W)
 d=[0]*-~W
 for _ in[0]*int(input()):
  v,w=map(int,input().split(','))
  for i in range(W,w-1,-1):
   if d[i]<d[i-w]+v:d[i]=d[i-w]+v
 print(f'Case {c}:\n{d[W]}\n{d.index(d[W])}')

Python: case = 0
while True:
    case += 1
    w_max = int(input())
    if w_max == 0:
        break
    n = int(input())

    w = [0 for i in range(n)]
    v = [0 for i in range(n)]
    for i in range(n):
        a, b = map(int, input().split(","))
        v[i] = a
        w[i] = b

    dp = [[0 for j in range(w_max + 1)] for i in range(n + 1)]
    for i in range(n)[::-1]:
        for j in range(w_max + 1):
            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])
    print("Case ",case,":",sep="")
    print(max(dp[0]))
    print(dp[0].index(max(dp[0])))

Python: c=0
for W in iter(input,'0'):
 c+=1
 W=int(W)
 dp=[0]*-~W
 for _ in[0]*int(input()):
  v,w=map(int,input().split(','))
  for i in range(W,w-1,-1):
   if dp[i]<dp[i-w]+v:dp[i]=dp[i-w]+v
 print(f'Case {c}:\n{dp[W]}\n{dp.index(dp[W])}')

Python: c = 0
while True:
  W = int(input())
  if W == 0:
    break
  c += 1
  N = int(input())

  vl = [0]
  wl = [0]
  for i in range(N):
    [v,w] = list(map(int,input().split(",")))
    vl.append(v)
    wl.append(w)
  dp = [[0 for i in range(W+1)] for j in range(N+1)]
  for i in range(N+1):
    for j in range(W+1):
      if i == 0 or j == 0:
        dp[i][j] = 0
      else:
        if wl[i] <= j:
          dp[i][j] = max(dp[i-1][j-wl[i]] + vl[i], dp[i-1][j])
        else:
          dp[i][j] = dp[i-1][j]
  ls = dp[N].copy()
  ls.reverse()
  max_w = W
  for i in range(1,W+1):
    if ls[i] == dp[N][W]:
      max_w -= 1
    else:
      break

  print("Case "+str(c)+":")
  print(dp[N][W])
  print(max_w)

Python: 

def rec(i, j):
	#print("rec({}, {}) called".format(i, j))
	if i in dphash and j in dphash[i]:
		return dphash[i][j]
	if i == N:
		ans = (0, W - j)
	elif j < wl[i]:
		ans = rec(i + 1, j)
	else:
		(v1, w1) = rec(i + 1, j)
		(v2, w2) = rec(i + 1, j - wl[i])
		v2 += vl[i]
		if v1 > v2:
			ans = (v1, w1)
		elif v1 < v2:
			ans = (v2, w2)
		elif v1 == v2:
			if w1 < w2:
				ans = (v1, w1)
			else:
				ans = (v2, w2)
	#dp[i][j] = ans
	if i in dphash:
		dphash[i][j] = ans
	else:
		dphash[i] = {}
		dphash[i][j] = ans

	return ans

case = 1
while True:
	W = int(input())
	if W == 0: break
	N = int(input())
	vl = []
	wl = []
	for _ in range(N):
		v, w = map(int, input().split(','))
		vl.append(v)
		wl.append(w)
	#dp = [[-1 for j in range(2500)] for i in range(2500)]
	dphash = {}
	(v, w) = rec(0, W)

	print("Case {}:".format(case))
	print(v)
	print(w)
	case += 1

Python: #!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import (division, absolute_import, print_function,
                        unicode_literals)
from sys import stdin
from itertools import count

def douteki(limit, data):
    V = [[0 for w in xrange(limit+1)] for i in xrange(len(data)+1)]
    W = [[0 for w in xrange(limit+1)] for i in xrange(len(data)+1)]
    for i in xrange(len(data)+1):
        for w in xrange(limit+1):
            diff = w - data[i-1][1]
            if i - 1 >= 0 and diff >= 0:
                v1 = V[i-1][diff] + data[i-1][0]
                w1 = W[i-1][diff] + data[i-1][1]
            else:
                v1 = 0
                w1 = 0
            v2 = V[i-1][w]
            w2 = W[i-1][w]

            V[i][w], W[i][w] = (v1, w1) if v1 >= v2 else (v2, w2)
    return V[-1][-1], W[-1][-1]

for case in count(1):
    W = int(stdin.readline())
    if not W:
        break

    N = int(stdin.readline())
    data = []
    for _ in xrange(N):
        data.append([int(s) for s in stdin.readline().split(',')])

    value, weight = douteki(W, data)
    print('Case {}:\n{}\n{}'.format(case, value, weight))

Python: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
import itertools

def solve(W, N, v):
    cache = {}
    def loop(i, w):
        if i == N:
            return (0, 0)
        if (i, w) in cache:
            return cache[i, w]
        cache[i, w] = loop(i + 1, w)
        if v[i][1] <= w:
            t = loop(i + 1, w - v[i][1])
            t = (t[0] + v[i][0], t[1] + v[i][1])
            if cache[i, w][0] < t[0] or cache[i, w][0] == t[0] and t[1] < cache[i, w][1]:
                cache[i, w] = t
        return cache[i, w]
    return loop(0, W)

for dn in itertools.count(1):
    W = int(input())
    if W == 0: break
    N = int(input())
    v = [tuple(map(int, input().split(','))) for _ in range(N)]
    optim = solve(W, N, v)
    print("Case %d:\n%d\n%d" % (dn, optim[0], optim[1]))

Python: # -*- coding: utf-8 -*-

import sys
import os
import math
import itertools

case = 1
for s in sys.stdin:

    # capacity
    C = int(s)
    if C == 0:
        break

    N = int(input())

    V = [0]
    W = [0]

    # max value table of (N+1) x (C+1)
    VT = [[0 for i in range(C+1)] for j in range(N+1)]
    WT = [[0 for i in range(C+1)] for j in range(N+1)]

    for i in range(N):
        v, w = map(int, input().split(','))
        V.append(v)
        W.append(w)

    for i in range(1, N+1):
        for j in range(1, C+1):
            if j >= W[i]:
                # can load
                value_on_load = VT[i-1][j - W[i]] + V[i]
                value_not_load = VT[i-1][j]

                weight_on_load = WT[i-1][j - W[i]] + W[i]
                weight_not_load = WT[i-1][j]

                if value_on_load > value_not_load:
                    VT[i][j] = value_on_load
                    WT[i][j] = weight_on_load
                elif value_on_load == value_not_load:
                    VT[i][j] = value_on_load
                    WT[i][j] = min(weight_on_load, weight_not_load)
                else:
                    VT[i][j] = value_not_load
                    WT[i][j] = weight_not_load
            else:
                VT[i][j] = VT[i - 1][j]
                WT[i][j] = WT[i - 1][j]

    print('Case {}:'.format(case))
    case += 1
    print(VT[N][C])
    print(WT[N][C])

Python: 

def rec(i, j):
	if dp[i][j] != -1:
		return dp[i][j]
	if i == N:
		ans = 0, W - j
	elif j < wl[i]:
		ans = rec(i + 1, j)
	else:
		v1, w1 = rec(i + 1, j)
		v2, w2 = rec(i + 1, j - wl[i])
		v2 += vl[i]
		if v1 > v2:
			ans = v1, w1
		elif v1 < v2:
			ans = v2, w2
		elif v1 == v2:
			if w1 < w2:
				ans = v1, w1
			else:
				ans = v2, w2
	dp[i][j] = ans
	return ans

while True:
	W = int(input())
	if W == 0: break
	N = int(input())
	vl = []
	wl = []
	for _ in range(N):
		v, w = map(int, input().split(','))
		vl.append(v)
		wl.append(w)
	dp = [[-1 for j in range(2000)] for i in range(2000)]
	v, w = rec(0, W)
	print(v, w)