Longest Simple Cycle(CF1476C)(线性dp)

题意:
\(n\) 条链,第 \(i\) 条链上有 \(c_{i}\) 个点,从第 \(2\) 条链开始,第 \(i\) 条链的首尾和第 \(i-1\) 条链的 \(a[i]\) 点、 \(b[i]\) 点相连接。问能构成的最大环的长度为多少。


想法:

  • 简单线性dp。
  • \(dp[i]\) 表示加上第 \(i\) 条边后的最大环的长度。
  • 显然 \(dp\) 方程为
    \(a[i]==b[i]\)时, \(dp[i]=c[i]+1\)
    \(a[i]!=b[i]\)时, \(dp[i]=c[i]+max(dp[i-1]+abs(a[i]-b[i])-1,abs(a[i]-b[i])+1)\)

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=100005;

ll a[maxn],b[maxn],c[maxn];
ll dp[maxn];
int main()
{
    int T,n;
    cin>>T;
    while(T--){
        memset(dp,0,sizeof dp);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&c[i]);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++)scanf("%lld",&b[i]);

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

posted @ 2021-02-12 21:37  hachuochuo  阅读(98)  评论(0编辑  收藏  举报