B - Reversi
题目链接:https://atcoder.jp/contests/agc031/tasks/agc031_b
题意:
给出n个数,然后现在你可以对一段区间修改成相同的值,前提是左右端点的值相同。问最后这n个数有多少种不同的值。
题解:
设dp[i]表示只考虑1~i这段,有多少不同的值。然后对于当前第i位,有两种选择,修改或者不修改,不修改的话就是dp[i-1];修改的话就是dp[k],这里k表示上一个相同颜色的位置。
注意一下如果i-1和i的颜色相同,当前要跳过,这个时候考虑修改是没有意义的。
代码如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 5, MOD = 1e9 + 7; int n; int c[N]; ll dp[N], sum[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; for(int i = 1; i <= n; i++) cin >> c[i]; dp[0] = 1; for(int i = 1; i <= n; i++) { if(c[i] == c[i - 1]) { dp[i] = dp[i - 1]; continue ; } dp[i] = (dp[i - 1] + sum[c[i]]) % MOD; sum[c[i]] = dp[i]; } cout << dp[n]; return 0; }