Problem:
泥棒

宝物がたくさん収蔵されている博物館に、泥棒が大きな風呂敷を一つだけ持って忍び込みました。盗み出したいものはたくさんありますが、風呂敷が耐えられる重さが限られており、これを超えると風呂敷が破れてしまいます。そこで泥棒は、用意した風呂敷を破らず且つ最も価値が高くなるようなお宝の組み合わせを考えなくてはなりません。

風呂敷が耐えられる重さ W、および博物館にある個々のお宝の価値と重さを読み込んで、重さの総和が W を超えない範囲で価値の総和が最大になるときの、お宝の価値総和と重さの総和を出力するプログラムを作成してください。ただし、価値の総和が最大になる組み合わせが複数あるときは、重さの総和が小さいものを出力することとします。

Input

複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。

W
N
v1,w1
v2,w2
:
vN,wN

１行目に風呂敷の耐えられる重さを表す整数 W (W ≤ 1,000)、２行目にお宝の数 N (1 ≤ N ≤ 1,000) が与えられます。続く N 行に i 番目のお宝の価値を表す整数 vi (0 ≤ vi ≤ 10,000) とその重さを表す整数 wi (0 ≤ wi ≤ W) の組がそれぞれ１行に与えられます。

W が 0 のとき入力の最後とします。データセットの数は 50 を超えません。

Output

各データセットに対して以下のように出力して下さい。

Case データセットの番号:
風呂敷に入れたお宝の価値総和
そのときのお宝の重さの総和

Sample Input

50
5
60,10
100,20
120,30
210,45
10,4
50
5
60,10
100,20
120,30
210,45
10,4
0

Output for the Sample Input

Case 1:
220
49
Case 2:
220
49

Solution in C# (judge verdict: Memory Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AOJ0042
{
    class Program
    {
        static void Main()
        {
            var count = 1;
            foreach (var bestCombination in from dataSet in ReadDataSets()
                                            select (from combination in PickTreasure(dataSet)
                                                    let price = combination.Sum(treasure => treasure.Price)
                                                    let weight = combination.Sum(treasure => treasure.Weight)
                                                    orderby weight ascending
                                                    orderby price descending
                                                    select new {combination, price, weight}).First())
            {

                Console.WriteLine("Case {0}:", count);
                Console.WriteLine(bestCombination.price);
                Console.WriteLine(bestCombination.weight);

                count++;
            }
        }

        public static IEnumerable<DataSet> ReadDataSets()
        {
            while (true)
            {
                var allowableWeight = int.Parse(Console.ReadLine() ?? "");
                if (allowableWeight == 0) yield break;

                var treasureCount = int.Parse(Console.ReadLine() ?? "");
                var treasures = new Treasure[treasureCount];

                for (var i = 0; i < treasureCount; i++)
                {
                    var values = (Console.ReadLine() ?? "").Split(',').Select(int.Parse).ToArray();
                    treasures[i] = new Treasure(values[0], values[1]);
                }

                yield return new DataSet(allowableWeight, treasures);
            }
        }

        public static IEnumerable<Treasure[]> PickTreasure(DataSet dataSet)
        {
            return PickTreasure(dataSet, new List<Treasure>());
        }

        private static IEnumerable<Treasure[]> PickTreasure(DataSet dataSet, List<Treasure> treasures)
        {
            int price;
            int weight;
            SumTreasures(treasures, out price, out weight);
            if (weight > dataSet.AllowableWeight) yield break;

            var feasibles = (from treasure in dataSet.Treasures
                            where !treasures.Contains(treasure)
                            where weight + treasure.Weight <= dataSet.AllowableWeight
                            select treasure).ToArray();

            if (!feasibles.Any())
            {
                yield return treasures.ToArray();
                yield break;
            }

            foreach (var comb in from newTreasure in feasibles
                                 let newTreasures = new List<Treasure>(treasures) {newTreasure}
                                 from combination in PickTreasure(dataSet, newTreasures)
                                 select combination)
            {
                yield return comb;
            }
        }

        private static void SumTreasures(IEnumerable<Treasure> treasures, out int price, out int weight)
        {
            price = 0;
            weight = 0;

            foreach (var treasure in treasures)
            {
                price += treasure.Price;
                weight += treasure.Weight;
            }
        }
    }

    public class DataSet
    {
        public DataSet(int allowableWeight, Treasure[] treasures)
        {
            AllowableWeight = allowableWeight;
            Treasures = treasures;
        }

        public int AllowableWeight { get; private set; }
        public Treasure[] Treasures { get; private set; }
    }

    public class Treasure
    {
        public int Price { get; private set; }
        public int Weight { get; private set; }

        public Treasure(int price, int weight)
        {
            Price = price;
            Weight = weight;
        }
    }
}