動的計画法の練習に入ります。私は、動的計画法を実装出来た事が無いです。なのでかなり練習しないとマズいと感じております(・・;)
また、今回私はボロボロなソースコードを実装して終了しました(泣)メモ化再帰と動的計画法の説明から問題に入ったのですが、動的計画法と再帰をあわせたやり方で解くみたいです(他にも解き方はたくさんあるようです)。メモ化再帰と動的計画法がうまく頭にイメージ出来ていない(深さ優先や幅優先をもう一度やり直した方がいいかもしれない)事が今回の失敗の原因と思われます。
問題元:SRM407 Div2 Level2
問題文:
あなたは巨大企業のHR部門で働いています。それぞれの従業員は直接のマネージャーを何人か、また直接の部下を何人か持つ事が出来ます。もちろん、部下達はそのまた部下をもつことがありますし、マネージャーたちはそのまたマネージャーを持つ事があり得ます。XがAのマネージャー、AがBのマネージャー、と続いて、DがYのマネージャであるような、従業員A,B.....Dのつながりがあるなら、従業員Xは従業員Yの上司であると言えます。
もちろん、XがYの直接のマネージャーであるなら、XはYの上司でしょう。もし、AがBの上司であるなら、BはAの上司である事は出来ません。新しい企業ポリシーによると、部下のいない従業員の給与は1です
。もし、従業員に何人か部下がいる場合、その従業員の給与は直接の部下達の給与の合計と等しくなります。
あなたには、String配列relationsを与えられます。この配列では、従業員iが従業員jの直接のマネージャである場合、i番目の要素のj番目の文字が'Y'になっており、そうでなければ'N'になっています。前従業員の給与の合計を返してください。
コード:
long totalSalary(String[] relations) {
if(relations.length == 1) return(1);
long[][] dp = new long[relations.length + 1][relations[0].length() + 1];
String comp = makeTop(relations.length);
for(int r = 0; r < relations.length; r++) {
if(relations[r].equals(comp)) {
dp[0][r] = 1;
}
}
for(int r = 0; r < relations.length + 1; r++) {
for(int c = 0; c < relations[r].length(); c++) {
if(relations[r].charAt(c) == 'Y') {
//どこをどう足せばいいかわからなくなってしまった
dp[r][r] += dp[r][c];
}
}
if(r != 0) {
for(int c = 0; c < relations[r].length(); c++) {
dp[r][c] += dp[r - 1][c];
}
}
}
int ret = 0;
for(int r = 0; r < relations.length + 1; r++) {
ret += dp[relations.length][r];
}
return(ret);
}