Problem:
Problem B: Moonlight Farm

あなたは大人気webゲーム「ムーンライト牧場」に熱中している．このゲームの目的は，畑で作物を育て，それらを売却して収入を得て，その収入によって牧場を大きくしていくことである．

あなたは速く畑を大きくしたいと考えた．そこで手始めにゲーム中で育てることのできる作物を，時間あたりの収入効率にもとづいて並べることにした．

作物を育てるには種を買わなければならない．ここで作物 i の種の名前は Li ，値段は Pi でそれぞれ与えられる．畑に種を植えると時間 Ai 後に芽が出る．芽が出てから時間 Bi 後に若葉が出る．若葉が出てから時間 Ci 後に葉が茂る．葉が茂ってから時間 Di 後に花が咲く．花が咲いてから時間 Ei 後に実が成る．一つの種から Fi 個の実が成り，それらの実は一つあたりSi の価格で売れる．一部の作物は多期作であり，計 Mi 回実をつける．単期作の場合は Mi = 1で表される．多期作の作物は，Mi 回目の実が成るまでは，実が成ったあと葉に戻る．ある種に対する収入は，その種から成った全ての実を売った金額から，種の値段を引いた値である．また，その種の収入効率は，その収入を，種を植えてから全ての実が成り終わるまでの時間で割った値である．

あなたの仕事は，入力として与えられる作物の情報に対して，それらを収入効率の降順に並べ替えて出力するプログラムを書くことである．

Input

入力はデータセットの列であり，各データセットは次のような形式で与えられる．

N

L1 P1 A1 B1
C1 D1 E1 F1
S1 M1

L2 P2 A2 B2
C2 D2 E2 F2
S2 M2

...

LN PN AN BN
CN DN EN FN
SN MN

一行目はデータセットに含まれる作物の数 N である (1 ≤ N ≤ 50)．

これに続く N 行には，各行に一つの作物の情報が含まれる．各変数の意味は問題文中で述べた通りである．作物の名前 Li はアルファベット小文字のみからなる20文字以内の文字列であり，また 1 ≤ Pi , Ai , Bi , Ci , Di , Ei , Fi , Si ≤ 100, 1 ≤ Mi ≤ 5である．一つのケース内に同一の名前を持つ作物は存在しないと仮定して良い．

入力の終りはゼロを一つだけ含む行で表される．

Output

各データセットについて，各行に一つ，作物の名前を収入効率の降順に出力せよ．収入効率が同じ作物に対しては，それらの名前を辞書順の昇順に出力せよ．

各データセットの出力の後には“#”のみからなる1行を出力すること．

Sample Input

5
apple 1 1 1 1 1 1 1 10 1
banana 1 2 2 2 2 2 1 10 1
carrot 1 2 2 2 2 2 1 10 2
durian 1 3 3 3 3 3 1 10 1
eggplant 1 3 3 3 3 3 1 100 1
4
enoki 1 3 3 3 3 3 1 10 1
tomato 1 3 3 3 3 3 1 10 1
potato 1 3 3 3 3 3 1 10 1
onion 1 3 3 3 3 3 1 10 1
3
a 10 1 1 1 1 1 1 10 1
b 10 2 2 2 2 2 2 10 1
c 10 2 2 2 2 2 2 10 1
0

Output for the Sample Input

eggplant
apple
carrot
banana
durian
#
enoki
onion
potato
tomato
#
b
c
a
#

Solution in C++ (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>
using namespace std;
int E[31][16],F[31][16],mem[31][51][6],used[31][51][6];
int D,c;

int dfs(int d,int cost,int x){
  if(D==d)return 0;
  if(used[d][cost][x]) return mem[d][cost][x];
  used[d][cost][x]=1;
  
  int res=dfs(d+1,cost,x);  

  for(int i=0;i<c;i++){
    int ncost=cost-F[i][d];
    if(!E[i][d]||ncost<0)continue;
    res=max(res,dfs(d+1,ncost,x)+E[i][d]);
    
    if(!x)continue;
    int ee=E[i][d],cc=ncost;
    for(int j=i+1;j<c;j++){
      ee+=E[j][d],cc-=F[j][d];
      if(!E[j][d]||cc<0)continue;
      res=max(res,dfs(d+1,cc,x-1)+ee);
    }
    
    ee=E[i][d],cc=ncost;
    for(int j=i-1;j>=0;j--){
      ee+=E[j][d],cc-=F[j][d];
      if(!E[j][d]||cc<0)continue;
      res=max(res,dfs(d+1,cc,x-1)+ee); 
    }
  }
  return mem[d][cost][x]=res;
}

int main(){
  int W,X;
  while(1){
    cin>>c>>D>>W>>X;
    if(!c&&!D&&!W&&!X) break;
    memset(used,0,sizeof(used)), memset(mem,0,sizeof(mem));
    for(int i=0;i<c;i++)for(int j=0;j<D;j++) cin>>E[i][j];
    for(int i=0;i<c;i++)for(int j=0;j<D;j++) cin>>F[i][j];
    cout << dfs(0,W,X)<<endl;
  }
  return 0;
}