zoukankan      html  css  js  c++  java
  • 20180418模拟赛T1——Seq

    Seq

    (seq.cpp/c/pas)

    题目描述 Description

    木吉要去征讨VAN様,所以他现在需要从他身边的人中选出若干位陪同。现在有(n)个人站成一行,木吉要从其中选出(2)批在这一行中连续的人(不能不选),且一个人不能两次都被选。每位人有一个战斗力(A_i),(A_i)可正可负。木吉团队的战斗力即为选择的人的(A_i)之和。
    现在木吉想要知道最大的战斗力是多少。

    输入描述 Input Description (seq.in)

    第一行为人数(n),第二行为(n)个整数依次为(A_1,A_2,cdots,A_n)

    输出描述 Output Description (seq.out)

    一个整数,即为最大的战斗力之和

    样例输入 Sample Input

    6
    10 -5 6 0 0 1

    样例输出 Sample Output

    17

    样例解释 Sample Interpretation

    第一批只选第一个人,第二批选第三、四、五、六个人

    数据范围 Data Size

    对于(30\%)的数据,(nle 50)(A_i)的绝对值不超过(1000)
    对于(60\%)的数据,(nle 5000)(A_i)的绝对值不超过(100000)
    对于(100\%)的数据,(nle 100000)(A_i)的绝对值不超过(1000000000)

    题解

    这张试卷中的人物名有点毒瘤

    一眼看是一道dp,于是开始大力转移。

    由于是分两批,于是想到需要分段处理。

    (i)号位置为最右端点的方案中最大战斗力为(ll[i]),同理定义(rr[i])

    那么显然有:(ll[i]=x[i]+max(ll[i-1],0),rr[i]=x[i]+max(rr[i+1],0))(贪心一下即可:如果前一位的最大值大于0,那么就加上前一位;否则就不加)。

    (lll[i])为前(i)位的最优方案,同理定义(rrr[i])(好吧我承认我的变量名有毒)。

    于是我们就可以很容易地推出:(lll[i]=max(lll[i-1],ll[i]),rrr[i]=max(rrr[i+1],rr[i]))(选与不选第(i)位)。

    最终,我们枚举断点(分成两段处理,取最大值):(ans=max(ans,lll[i]+rrr[i+1]))

    代码如下

    #include <cstdio>
    #include <cctype>
    #include <iostream>
    
    using namespace std;
    
    typedef long long LL;
    
    #define dd c=getchar()
    inline void read(LL& x)
    {
    	x=0;int dd;bool f=false;
    	for(;!isdigit(c);dd)if(c=='-')f=true;
    	for(;isdigit(c);dd)	x=(x<<1)+(x<<3)+(c^48);
    	if(f)x=-x;return;
    }
    #undef dd
    
    const LL INF=0x3f3f3f3f3f3f3f3f;
    const LL maxn=100005;
    
    LL ll[maxn],rr[maxn];
    LL lll[maxn],rrr[maxn];
    LL x[maxn];
    
    int main()
    {
    	freopen("seq.in","r",stdin);
    	freopen("seq.out","w",stdout);
    	LL n;read(n);
    	lll[0]=rrr[n+1]=-INF;
    	for(LL i=1;i<=n;++i)
    	{
    		read(x[i]);
    		ll[i]=x[i]+max(ll[i-1],0LL);
    	}
    	for(LL i=n;i;--i)
    		rr[i]=x[i]+max(rr[i+1],0LL);
    	LL ans=-INF;
    	for(LL i=1;i<=n;++i)
    		lll[i]=max(lll[i-1],ll[i]);
    	for(LL i=n;i;--i)
    		rrr[i]=max(rrr[i+1],rr[i]);
    	for(int i=1;i<n;++i)
    		ans=max(ans,lll[i]+rrr[i+1]);
    	printf("%lld",ans);
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    DHCP三种配置
    Linux-9引导过程与服务控制
    Linux系统管理10-进程和计划任务管理
    Linux系统管理11-系统安全及应用
    Linux系统管理12-Linux文件系统与日志
    ---01--Lin网络基础设置
    服务器RAID及磁盘配额的配置
    Linux常见故障及修复方法
    作业5
    104 权限 sudo 解压缩
  • 原文地址:https://www.cnblogs.com/pfypfy/p/8903234.html
Copyright © 2011-2022 走看看