题目 | Box
2023牛客暑期多校训练营2
K - Box
https://ac.nowcoder.com/acm/contest/57356/K
题意
给出一个长度为 $n$ 的 $01$ 串以及每个位置都有权值 $a_i \geq 0$ ,每个 $1$ 最多移动一次且最多移动一位。若一个位置有 $1$ 则可以获得权值,问最大可能的权值和。
$n \leq 10^6$。
题解
状态表示:
$a_i:=$ 权重数组
$b_i:=$ $01$ 数组
$dp_{ij}:=$ 考虑数列 $1\sim i$ 位,$j=0$ 代表此处的 $1$ 挪到上一位,$j=1$ 代表此处的 $1$ 不动,$j=2$ 代表此处的 $1$ 挪到下一位,此时的最大权值和为 $dp_{ij}$.
状态计算:
若 $b_i=0$
- $dp_{i,0}=dp_{i-1,0}$
- $dp_{i,1}=dp_{i-1,1}$
- $dp_{i,2}=dp_{i-1,2}$
若 $b_i=1$
如果与上一个 $1$ 的距离为 $1$:初始状态为 $11$(下面的箭头代表 $1$ 的初始位置)
- $dp_{i,0}=dp_{i-1,0}+a_{i-1}$:代表情况为 $1\underset{\hat{\ }}1\underset{\hat{\ }}00$
- $dp_{i,1}=\max\{dp_{i-1,0},dp_{i-1,1}\}+a_{i}$:代表情况为 $\max\{1\underset{\hat{\ }}0\underset{\hat{\ }}10,0\underset{\hat{\ }}1\underset{\hat{\ }}10\}$
- $dp_{i,2}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i+1}$:代表情况为 $\max\{1\underset{\hat{\ }}0\underset{\hat{\ }}01,0\underset{\hat{\ }}1\underset{\hat{\ }}01,0\underset{\hat{\ }}0\underset{\hat{\ }}11\}$
如果与上一个 $1$ 的距离为 $2$:初始状态为 $101$
- $dp_{i,0}=\max\{dp_{i-1,0},dp_{i-1,1}\}+a_{i-1}$:代表情况为 $\max\{1\underset{\hat{\ }}01\underset{\hat{\ }}00,0\underset{\hat{\ }}11\underset{\hat{\ }}00\}$
- $dp_{i,1}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i}$:代表情况为 $\max\{1\underset{\hat{\ }}00\underset{\hat{\ }}10,0\underset{\hat{\ }}10\underset{\hat{\ }}10,0\underset{\hat{\ }}01\underset{\hat{\ }}10\}$
- $dp_{i,2}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i+1}$:代表情况为 $\max\{1\underset{\hat{\ }}00\underset{\hat{\ }}01,0\underset{\hat{\ }}10\underset{\hat{\ }}01,0\underset{\hat{\ }}01\underset{\hat{\ }}01\}$
如果与上一个 $1$ 的距离为 $\geq3$:初始状态为 $10\dots01$
- $dp_{i,0}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i-1}$:代表情况为 $\max\{1\underset{\hat{\ }}00\dots1\underset{\hat{\ }}00,0\underset{\hat{\ }}10\dots1\underset{\hat{\ }}00,0\underset{\hat{\ }}01\dots1\underset{\hat{\ }}00\}$
- $dp_{i,1}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i}$:代表情况为 $\max\{1\underset{\hat{\ }}00\dots0\underset{\hat{\ }}10,0\underset{\hat{\ }}10\dots0\underset{\hat{\ }}10,0\underset{\hat{\ }}01\dots0\underset{\hat{\ }}10\}$
- $dp_{i,2}=\max\{dp_{i-1,0},dp_{i-1,1},dp_{i-1,2}\}+a_{i+1}$:代表情况为 $\max\{1\underset{\hat{\ }}00\dots0\underset{\hat{\ }}01,0\underset{\hat{\ }}10\dots0\underset{\hat{\ }}01,0\underset{\hat{\ }}01\dots0\underset{\hat{\ }}01\}$
代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int> a(n + 10), b(n + 10);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
vector<vector<int>> dp(n + 10, vector<int>(3));
int last = -2;
for (int i = 1; i <= n; i++)
{
if (b[i] == 1)
{
if (i - last == 1)
{
dp[i][0] = dp[i - 1][0] + a[i - 1];
dp[i][1] = max({dp[i - 1][0], dp[i - 1][1]}) + a[i];
dp[i][2] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i + 1];
}
else if (i - last == 2)
{
dp[i][0] = max({dp[i - 1][0], dp[i - 1][1]}) + a[i - 1];
dp[i][1] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i];
dp[i][2] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i + 1];
}
else
{
dp[i][0] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i - 1];
dp[i][1] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i];
dp[i][2] = max({dp[i - 1][0], dp[i - 1][1], dp[i - 1][2]}) + a[i + 1];
}
last = i;
}
else
{
dp[i][0] = dp[i - 1][0];
dp[i][1] = dp[i - 1][1];
dp[i][2] = dp[i - 1][2];
}
}
cout << max({dp[n][0], dp[n][1], dp[n][2]}) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi