AGC 031 B - Reversi
このAGCは引越の疲れで参加できてなかった...
- 問題
- 解法
手で実験してみるとDPぽいな〜と思ったのでDPを考えます.
に対する塗り方の個数
とします.
色が切り替わるときに注目します.
いま,j+1番目の石を見ているとしましょう.
さらにj+1番目の石の色と同じ色の石で,(j以下で)j+1に最も近いものの位置をiとします.
このとき,iとj+1番目の石を選んで操作を行ったときの色の塗り方はの塗り方の個数なのでです.
iとj+1番目の石に対して操作を行わなかったときの色の塗り方はです.
したがってであることが分かります.
各色に対して,1番右側にあるものの位置(またはそのdpの値)を記憶しておけば,j+1番目の石の色と同じ色の石で,(j以下で)j+1に最も近いものの位置(またはそのdpの値)はで求められます.
結局,この問題はで解けることになります.
#include <iostream> #include <vector> using namespace std; typedef long long int ll; const ll mod = 1e9+7; const ll MAXN = 2*1e5+1; int main() { ll n; cin>>n; vector<ll> c(n); for(int i = 0; i < n; i++){ cin>>c[i]; } vector<ll> dp(MAXN,0); dp[c[0]]=1; for(int i = 1; i < n; i++){ if(c[i]!=c[i-1]){ dp[c[i]] = (dp[c[i]]+dp[c[i-1]]) % mod; } } cout << dp[c[n-1]] << endl; return 0; }