ABC240 C - Jumping Takahashi C++解答例
AtCoder Beginner Contest 240 C - Jumping TakahashiをC++で解きます。
問題
問題文をAtCoder のページより引用します。
問題文
高橋君は数直線状の座標
の位置にいます。 0
これから高橋君は回のジャンプを行います。 N 回目のジャンプでは、正の方向に i(1 \leq i \leq N) または a_i 移動します。 b_i
回のジャンプの後に座標 N の位置にいるようにすることはできますか? X
制約
1 \leq N \leq 100 1 \leq a_i < b_i \leq 100 \quad (1 \leq i \leq N) 1 \leq X \leq 10000 - 入力は全て整数
解答例
動的計画法で解く
このような特性を持つ問題は動的計画法で解くことができます。
DP テーブルの設計
DP テーブルを以下のように定義します。
DP テーブルの初期条件は以下のように設定します。
まだ1回もジャンプをしていないとき、すでに座標0にいるので、
DP の遷移
- 今いる位置から正の方向に
だけ飛ぶa_i - 今いる位置から正の方向に
だけ飛ぶb_i
同様に、
したがって、DPの遷移の漸化式は以下のようになります。
真を偽で上書きしないように、結果のORを取るようにしています。
プログラム実装例
C++のプログラム実装例を以下に示します。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main() {
int64_t N, X;
std::cin >> N >> X;
std::vector<int64_t> A(N + 1);
std::vector<int64_t> B(N + 1);
for (int64_t i = 1; i <= N; i++) {
std::cin >> A.at(i) >> B.at(i);
}
// DPテーブル
std::vector<std::vector<bool>> dp(N + 1, std::vector<bool>(X + 1, 0));
// 初期条件
dp.at(0).at(0) = true;
// DP遷移
for (int64_t i = 1; i <= N; i++) {
for (int64_t j = 0; j <= X; j++) {
// i回目のジャンプでaを選ぶとき
if (j - A.at(i) >= 0) {
dp.at(i).at(j) = dp.at(i).at(j) || dp.at(i - 1).at(j - A.at(i));
}
// i回目のジャンプでbを選ぶとき
if (j - B.at(i) >= 0) {
dp.at(i).at(j) = dp.at(i).at(j) || dp.at(i - 1).at(j - B.at(i));
}
}
}
if (dp.at(N).at(X)) {
std::cout << "Yes" << std::endl;
} else {
std::cout << "No" << std::endl;
}
return 0;
}
実際に提出したコードはこちら。
Discussion