0%

Educational Codeforces Round 103 - C - Longest Simple Cycle

题目

https://codeforces.com/contest/1476/problem/C

思路

设$dp(i,j)$,$i$表示第$i$条链,$j$表示是否和第$i-1$条链连接,0表示不连接,1表示连接
考虑不连接的情况,对于第$i$条链,显然当前状态由第$i-1$条链的状态直接转移,即$dp(i,0)\leftarrow\max(dp(i-1,0),dp(i-1,1))$
考虑连接的情况,有三种转移方程:
当$a_i=b_i$时,只能从第$i$条链向左出发,到$i-1$返回,此时状态转移方程为$dp(i,1)\leftarrow c_i-1+2$
当$a_i\not=b_i$且$i-1=1$,此时与第一种情况一样,状态转移方程为$dp(i,1)\leftarrow dp(i-1,1)+2+c_i-1$
当$a_i\not=b_i$且$i-1\not=1$,此时的路径可能到$i-1$返回,也有可能到$i-2$、$i-3$返回等等,考虑到最优子结构,$i-2$、$i-3$以及后面的这些情况已经被最优选择,所以只需考虑$i-1$返回和非$i-1$返回的情况即可
此时的状态转移方程为$dp(i,1)\leftarrow\max(dp(i-1,1)-\vert a_i-b_i\vert+2+c_i-1,\vert a_i-b_i\vert+2+c_i-1)$

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
#define endl '\n'
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define lowbit(x) (x&-x)
using namespace std;
struct _IO { _IO() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); } }_io;
typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<ll, ll> pll;

const ll maxn = 1e5 + 5;;
ll a[maxn], b[maxn], c[maxn], dp[maxn][2];

int main()
{
ll T;
cin >> T;
while (T--)
{
ll n;
cin >> n;
for (ll i = 1; i <= n; ++i) cin >> c[i];
for (ll i = 1; i <= n; ++i) cin >> a[i];
for (ll i = 1; i <= n; ++i) cin >> b[i];

dp[1][1] = abs(a[2] - b[2]);
for (ll i = 2; i <= n; ++i)
{
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
if (a[i] == b[i])
{
dp[i][1] = c[i] - 1 + 2;
}
else
{
if (i - 1 == 1) dp[i][1] = dp[i - 1][1] + 2 + c[i] - 1;
else dp[i][1] = max(dp[i - 1][1] - abs(a[i] - b[i]) + 2 + c[i] - 1, abs(a[i] - b[i]) + 2 + c[i] - 1);
}
}

cout << max(dp[n][0], dp[n][1]) << endl;
}
return 0;
}