AOJ0557 A First Grader

「AOJ0557 A First Grader」の編集履歴(バックアップ)一覧はこちら

AOJ0557 A First Grader - (2013/10/31 (木) 03:47:54) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

*AOJ0557 A First Grader **サイト [http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0557] 参考サイト **解説 +と-の2択を選びつつ様々な制限の元ansに一致する場合数を列挙します。 2択で処理を進めるので全探索するとO(2^n)です。取りあえず再帰で全探索コードを考えてみましょう。 数列中の今見ている項とそこまでの計算結果の2つの情報が必要です。例外処理を省略して書いてみます。 >|| int rec(int index, int sum) { if(index == tail) return sum == ans; return rec(index+1, sum + seq[index+1]) + rec(index+1, sum - seq[index+1]); } ||< 同じ項を見ているときそこまでの計算結果も同じなら、その後の計算が無駄になります。計算結果を再利用しましょう。メモ化再帰です。 >|| int rec(int index, int sum) { if(memo[index][sum] == -1) return memo[index][sum]; if(index == tail) return sum == ans; return memo[index][sum] = rec(index+1, sum + seq[index+1]) + rec(index+1, sum - seq[index+1]); } ||<
*AOJ0557 A First Grader **サイト [http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0557] 参考サイト **解説 +と-の2択を選びつつ様々な制限の元ansに一致する場合数を列挙します。 2択で処理を進めるので全探索するとO(2^n)です。取りあえず再帰で全探索コードを考えてみましょう。 数列中の今見ている項とそこまでの計算結果の2つの情報が必要です。例外処理を省略して書いてみます。 >|| int rec(int index, int sum) { if(index == tail) return sum == ans; return rec(index+1, sum + seq[index+1]) + rec(index+1, sum - seq[index+1]); } ||< 同じ項を見ているときそこまでの計算結果も同じなら、その後の計算が無駄になります。計算結果を再利用しましょう。メモ化再帰です。 >|| int rec(int index, int sum) { if(memo[index][sum] == -1) return memo[index][sum]; if(index == tail) return sum == ans; return memo[index][sum] = rec(index+1, sum + seq[index+1]) + rec(index+1, sum - seq[index+1]); } ||< これで無駄な計算が無くなり、O(ns) 100*21 = 2100通りとなりました。 DPしてみましょう。高校数学の漸化式のと同じように「初期条件」と「式そのもの」が必要です。

表示オプション

横に並べて表示:
変化行の前後のみ表示: