2021西电校赛网络选拔赛 D.咕的头发问题 (dp)

Posted Accelerator

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021西电校赛网络选拔赛 D.咕的头发问题 (dp)相关的知识,希望对你有一定的参考价值。

  • 题意:有\\(n\\)个数,可以使任意两个子数组(不重叠)的元素贡献*2,问你操作后整个数组的最大元素和是多少.

  • 题解:假如我们只能操作的一次的话,这题完全可以转换为求最大子段和,即先求出所有元素和,然后再加上最大子段和即可,但是现在我们需要求出两个最大子段和,也就意味着在操作一次的基础上,可以使区间断开分成两个,可是这样dp方程并不好转移,但根据这个断开的思想,我们不难想到可以正序和倒序分别求出两个最大子段和,然后维护一下前缀最大和后缀最大,最后枚举断开的位置,在所有元素和的基础上再加上前缀和后缀即可.

  • 代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int n;
    ll a[N];
    ll dp[N][2];
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	cin>>n;
    	rep(i,1,n) cin>>a[i];
    
    	rep(i,1,n){
    		dp[i][0]=max(a[i],dp[i-1][0]+a[i]);
    	}
    	per(i,n,1){
    		dp[i][1]=max(a[i],dp[i+1][1]+a[i]);
    	}
    	rep(i,1,n){
    		dp[i][0]=max(dp[i][0],dp[i-1][0]);
    	}
    	per(i,n,1){
    		dp[i][1]=max(dp[i][1],dp[i+1][1]);
    	}
    	ll sum=0;
    	rep(i,1,n){
    		sum+=a[i];
    	}
    	ll ans=-1e18;
    	rep(i,1,n){
    		ans=max(ans,sum+dp[i-1][0]+dp[i][1]);	
    	}
    
    
    	cout<<ans<<\'\\n\';
    
        return 0;
    }
    
    

以上是关于2021西电校赛网络选拔赛 D.咕的头发问题 (dp)的主要内容,如果未能解决你的问题,请参考以下文章

西电2021校赛选拔赛 C.扶梯问题 (贪心,枚举)

2021CCPC网络选拔赛题解

2021-4-27 CSUST 银川选拔赛补题

2021-4-27 CSUST 银川选拔赛补题

2021-4-27 CSUST 银川选拔赛补题

南昌大学航天杯第二届程序设计竞赛校赛网络同步赛 D