从题目中可以读到:给定的预测结果与 i , i − 1 , i − 2 i,i-1,i-2 i,i−1,i−2有关且前 2 2 2点无法预测,如果要得到最多的绿岛数量,那么我们应该考虑枚举所有可能的构成序列。
定义 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示考虑到第 i i i个字符,当前结尾的三个字符 i , i − 1 , i − 2 i,i-1,i-2 i,i−1,i−2分别存放了 j , k , l ( ∈ { 1 , 2 , 3 } ) j,k,l(\in\{1,2,3\}) j,k,l(∈{1,2,3})时的最大绿岛数,可以得到转移方程:(注意要初始化不可以是 0 0 0,因为 0 0 0也属于合法情况) d p [ i ] [ j ] [ k ] = max ( d p [ i − 1 ] [ j ] [ k ] , d p [ i − 1 ] [ k ] [ l ] + ( j = = 2 ) ) dp[i][j][k] = \max(dp[i - 1][j][k], dp[i - 1][k][l] + (j == 2)) dp[i][j][k]=max(dp[i−1][j][k],dp[i−1][k][l]+(j==2)) 在转移过程中,需要排掉不符合实际情况的状态:
a[i] == 'R'
要求
c
n
t
R
>
c
n
t
G
cnt_R > cnt_G
cntR>cntG
a[i] == 'G'
要求
c
n
t
G
>
c
n
t
R
cnt_G > cnt_R
cntG>cntR
a[i] == 'B'
要求
c
n
t
R
=
c
n
t
G
cnt_R = cnt_G
cntR=cntG
#include
using namespace std;
const int N = 1e5 + 10;
char a[N];
int dp[N][3][3];
inline void solve(){
int n = 0; cin >> n >> a + 1;
memset(dp, -0x3f, sizeof dp);
for(int i = 0; i
关注
打赏
- 回坑记之或许是退役赛季?
- [LCT刷题] P1501 [国家集训队]Tree II
- [LCT刷题] P2147 洞穴勘测
- 2022-2023 ICPC Brazil Subregional Programming Contest VP记录
- [线段树套单调栈] 2019-2020 ICPC Asia Hong Kong Regional Contest H.[Hold the Line]
- The 2021 ICPC Asia Nanjing Regional Contest E.Paimon Segment Tree 区间合并线段树/维护矩阵乘法
- CF580E - Kefa and Watch 线段树维护哈希
- HDU5869 Different GCD Subarray Query 离线查询/区间贡献
- 27.CF1004F Sonya and Bitwise OR 区间合并线段树
- 26.CF1000F One Occurrence