[AtCoder] ABC 175 D – Moving Piece
問題
方針
マス \( i \) を選択したとき、\( N \) 回以下の移動でマス \( i \) に戻ってくるので、\( K \) 回以下の移動で何周できるかを考えます。周回しない方が最適な場合もあることに注意します。マス \( i \) を含むサイクルの長さを \( l_i \) とすると、マス \( i \) から \( n (1 \leq n < l_i) \) 回移動したとき、周回できる回数は、
\[ \left \lfloor \dfrac{K – n}{l_i} \right \rfloor\]
となります。したがって、全てのマスを全探索します。
コード
#include <bits/stdc++.h> using namespace std; typedef long long int ll; int main() { int N; ll K; cin >> N >> K; int P[N]; ll C[N]; for (int i = 0; i < N; i++) { cin >> P[i]; P[i]--; } for (int i = 0; i < N; i++) { cin >> C[i]; } ll ans = -100000000000000; for (int i = 0; i < N; i++) { vector<ll> v; int p = P[i]; ll c_sum = C[p]; ll cnt = 1; ans = max(ans, c_sum); while (true) { p = P[p]; if (P[i] == p) break; cnt++; if (cnt > K) break; c_sum += C[p]; ans = max(ans, c_sum); } ll sum = 0; p = P[i]; if (cnt > K) continue; ans = max(ans, c_sum * (K / cnt)); for (int i = 0; i < cnt; i++) { sum += C[p]; p = P[p]; ans = max(ans, sum + c_sum * ((K - i - 1)/ cnt)); } } cout << ans << "\n"; return 0; }
ディスカッション
コメント一覧
まだ、コメントがありません