C. Longest Simple Cycle - Educational Codeforces Round 103 (Rated for Div. 2)补题·

C. Longest Simple Cycle

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

思路

题意是给出一个由n条链连接成的图,求出最长的循环圈的长度。其中ci表示第i条链的顶点个数,ai和bi表示第i条链起点和终点所连接的上一条链的点的编号。

考虑位置i(i>=2),枚举最大值,每个位置都可能是最大值的终点

  • 当i=2或者ai=bi时,此时只能上一条链为循环圈的起点,假设到达当前链为最优(sum=b[i]-a[i]+1+c[i]),跟答案求一次max

  • 当i属于其他情况时,此时有两种情况可供考虑,
    1.以上一条链为起点(sum=b[i]-a[i]+c[i]+1)
    2.继续延续从前面来的最优解情况,(sum=sum-(b[i]-a[i])+1+c[i]),注意当考虑第i-1条链的最优解时已经把c[i-1]加了,所以此时sum-(b[i]-a[i])即是以第i-1条链可用作循环圈的边数,+1是因为
    两条链中间需要两条链:c[i]-1+b[i]-a[i]+2=c[i]+b[i]-a[i]+1。
    取这两种情况的最优解即可。

注意这里假设了b[i]>a[i],运算时需要取绝对值。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=1e5+7;
const ll mod=998244353;       

ll a[N],b[N],c[N],dp[N];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){  
        int n;
        cin>>n;
        for (int i = 1; i <= n; ++i)
        {
            cin>>c[i];
        }
        for (int i = 1; i <= n; ++i)
        {
            cin>>a[i];
        }
        for (int i = 1; i <= n; ++i)
        {
            cin>>b[i];
        }ll ans=0,sum=0;
        for (int i = 2; i <= n; ++i)
        {
            if(a[i]==b[i]||i==2){
                sum=c[i]+1+abs(a[i]-b[i]);
            }else{
                sum=max(sum-abs(a[i]-b[i])+1+c[i],abs(a[i]-b[i])+1+c[i]);
            }ans=max(ans,sum);
        }cout<<ans<<endl;
        
    }
    return 0;
}

C题也是差一点就出来了,我太菜了

posted @ 2021-01-30 11:36  !^^!  阅读(259)  评论(0编辑  收藏  举报