ABC240C - Jumping Takahashi

考え方

「入力の全てのパターンに対応する到達地点を調べる」方法だと$2^{100} = (1024)^{10} \sim 10^{30}$で間に合わない.

到達地点の候補は,$1\leq X \leq 10,000$の範囲なので,$10^{30}$よりずっと小さい.そこで,到達地点としてあり得る範囲を全探索できないか考える.

「各入力に対して,到達地点を($1\leq X \leq 10,000$の範囲で)全探索する」とすれば,$2\times 100 \times 10,000 \sim 10^{6}$となり間に合うことがわかる.


【補足】$2^{100}$の考え方では,$1\leq X \leq 10,000$の範囲外を考える必要があったり,あるステップで同一地点に来る方法が何通りもあると次のステップではそれらを全て区別して考えるので処理量が増えている.

回答例

N, X = map(int, input().split())

dp = [[False] * 10001 for _ in range(201)]
dp[0][0] = True
for i in range(N):
  a, b = map(int, input().split())
  for j in range(X + 1):
    if j + a <= X:
      dp[i + 1][j + a] |= dp[i][j]
    if j + b <= X:
      dp[i + 1][j + b] |= dp[i][j]
    
print('Yes' if dp[N][X] else 'No')

【参考】Submission #29516088 - AtCoder Beginner Contest 240

配列再利用をする際は,ピッタリ$N$回で$X$に到達する必要があることに気をつける.

N, X = map(int, input().split())

dp = [-1] * 10001
dp[0] = 0
for i in range(N):
  a, b = map(int, input().split())
  for j in range(X, -1, -1):
    if j + a <= X and dp[j] == i:
      dp[j + a] = dp[j] + 1
    if j + b <= X and dp[j] == i:
      dp[j + b] = dp[j] + 1

print('Yes' if dp[X] == N else 'No')

【参考】Submission #29517173 - AtCoder Beginner Contest 240