Problem:
Problem D:THE BYDOLM@STER

Description

THE BYDOLM@STER(バイドルマスター)とは1rem社より2010/4/1にEXIDNAで発売が予定されている育成シミュレーションゲームである。一応断っておくが、今月初めにネットワーク接続サービスが停止した某アーケードゲームとはたぶん関係が無い。

このゲームはバイドルたちからプロデュースするユニット(編隊)のメンバーを選択し、メンバーたちとのレッスンやコミュニケーションを通じて、彼女(彼)らをバイドルの頂点、トップバイドルに育て上げるゲームである。

各バイドルには能力値としてボーカル、ダンス、ルックスの3つのパラメータを持ち、ユニットの能力値はユニットに属している全てのバイドルのパラメータの合計値となる。ユニットの3つの能力値のうち最大の物がユニットのランクとなる。

ユニットに人数制限は無く、メンバーの人数が1体でも、3体でも、100体でもユニットとして活動できる。もちろん同じバイドルを複数雇うこと出来るが、バイドルを雇うためには費用がかかるのでこれを考慮に入れなければならない。

プロデューサーであるあなたは最高のユニットを作るためにプログラムを書いて計算することにした。

Input

入力は複数のテストケースからなる。

各テストケースの1行目にはバイドルの数Nと使用可能な費用Mが与えられる。(1<=N,M<=300)
次の2*N行には各バイドルに関しての情報が書かれている。

バイドルの情報の1行目にはバイドルの名前。バイドルの名前はアルファベットと空白から成り、30文字を以下である。また同一名のバイドルは存在しない。

2行目には整数C、V、D、Lが与えられる。Cはそのバイドルを1体雇用するコスト、Vはボーカル、Dはダンス、Lはルックスの能力値を表す。(1<=C,V,D,L<=300)

入力はEOFで終わる。

Output

与えられた費用の中で作れるユニットのランクの最大値を答えよ。

ユニットが作れない場合は0を出力せよ。

Sample Input

3 10
Dobkeradops
7 5 23 10
PataPata
1 1 2 1
dop
5 3 11 14
2 300
Bydo System Alpha
7 11 4 7
Green Inferno
300 300 300 300

Output for Sample Input

29
462

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
public class Main {
	static Scanner sc = new Scanner(System.in);
	static int[][] dp;
	static String name;
	static int N, M;
	static int[] C, V, D, L;
	public static void main(String[] args) {
		while(read()){
			solve();
		}
	}
	static boolean read(){
		if(!sc.hasNext())
			return false;
		N = sc.nextInt(); M = sc.nextInt();
		dp = new int[N+1][M+1];
		C = new int[N]; V = new int[N]; D = new int[N]; L = new int[N];
		for(int i = 0; i < N; i++){
			String str;
			do{
				str = sc.next();
			}while(!Character.isDigit(str.charAt(0)));
			C[i] = Integer.parseInt(str);
			V[i] = sc.nextInt(); D[i] = sc.nextInt(); L[i] = sc.nextInt();
			}

		return true;
	}
	static void solve(){
		int ans = Math.max(selectVocal(), selectDance());
		ans = Math.max(ans, selectLooks());
		System.out.println(ans);
	}
	static int selectVocal(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + V[i]);
				}
			}
		}
		return dp[N][M];
	}
	static int selectDance(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + D[i]);
				}
			}
		}
		return dp[N][M];
	}
	static int selectLooks(){
		for(int i = 0; i < N; i++){
			for(int j = 0; j <= M; j++){
				if(j < C[i]){
					dp[i + 1][j] = dp[i][j];
				}else{
					dp[i + 1][j] = Math.max(dp[i][j], dp[i + 1][j - C[i]] + L[i]);
				}
			}
		}
		return dp[N][M];
	}

}