CF 1743C - Save the Magazines(简单DP)
C - Save the Magazines(简单DP)
题意
现在有n个盖子,每个盖子下面有权值,当盖子盖着的时候,这个权值就会成为你的贡献之一。对于每个盖子(除了第一个),你最多可以将其往前移动一次。给出原有的盖子的分布,请输出这个贡献的最大值。
思路
比赛的时候写的太慢,现在写个题解来总结一下思路。很明显,直接贪心是有后效性的,所以我们直接想到DP。对于每个盖子,可以往前移动或者不往前移动,还有一个区别就是这个地方本来有盖子,我们才能将其往前移动,不然不能。按照上面的思路直接递推过去就好了。
实现
当s[i]不为1的时候,\(f_{i,1}\)也是可以存在的,只是他的值和\(f_{i,0}\)一样,不会影响递推的结果。
const int N = 200005;
int n;
int ar[N];
int f[N][2];
void solve()
{
string s;
cin >> n >> s;
s = '0' + s;
for(int i = 1; i <= n; i ++)
cin >> ar[i];
f[0][0] = f[0][1] = 0;
for(int i = 1; i <= n; i ++)
{
if(s[i] == '1')
{
f[i][1] = max(f[i - 1][0], f[i - 1][1]) + ar[i];
f[i][0] = f[i - 1][0] + ar[i - 1];
}
else
{
f[i][0] = f[i][1] = max(f[i - 1][0], f[i - 1][1]);
}
}
cout << max(f[n][0], f[n][1]) << '\n';
}