思路
从题目中可以读到:给定的预测结果与 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
Accepted Code
#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
