zoukankan      html  css  js  c++  java
  • C 娜娜梦游仙境系列——吃不完的糖果

    C - 娜娜梦游仙境系列——吃不完的糖果

    Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others)

    Problem Description

    娜娜好不容易才在你的帮助下"跳"过了这个湖,果然车到山前必有路,大战之后必有回复,大难不死,必有后福!现在在娜娜面前的就是好多好多的糖果还有一些黑不溜秋的东西!不过娜娜眼中只有吃不完的糖果!娜娜高兴地快要蹦起来了!

    这时有一位挥着翅膀的女孩(天使?鸟人?)飞过来,跟娜娜说,这些糖果是给你的~(娜娜已经两眼放光)~你可以带走~(娜娜已经流下了口水)~但是~(神马?还有但是?)~这位神仙姐姐挥一挥翅膀~飘过了一片云彩,糖果和那些黑不溜秋的东西顿时飞了起来,落到地上成了摆成一个奇怪的图形。

    神仙姐姐很满意,转过来对娜娜说:“这些糖果和黑洞(神马?黑洞?)分成n堆,每堆要么都是糖果,要么是黑洞,围成一个圈(即第1堆的旁边是第n堆和第2堆),你可以选择连续若干堆,然后带走,不过这些黑洞嘛,会馋嘴的小孩吸进去,你必须拿糖果去中和掉。”

    娜娜喜欢糖果,但不喜欢动脑子~于是就把这个问题交给你,怎样才能让娜娜带走最多的糖果呢?

    Input

    多组数据,首先是一个正整数t(t<=20)表示数据组数

    对于每组数据,包括两行,第一行是一个正整数n(3<=n<=100000)表示堆数

    第二行是n个整数x[i](1<=|x[i]|<=1000),如果是个正整数,则说明这是一堆数量为x[i]的糖果,如果是个负整数,则说明这是一个需要用abs(x[i])颗糖果去中和的黑洞。

    Output

    对于每组数据,输出一个整数,表示娜娜最多能带走的糖果数。

    Sample Input

    3
    5
    1 2 3 4 5
    5
    1 -2 3 -4 5
    5
    -1 -2 -3 -4 -5

    Sample Output

    15
    7
    0

    Hint

    对于样例1,娜娜可以把所有的糖果都拿走,所以输出15(=1+2+3+4+5)

    对于样例2,娜娜可以拿走第1,2,3,5堆的糖果,别忘了这是摆成一个圈,所以输出7(=1+(-2)+3+5)

    对于样例3,等待娜娜的是5个黑洞,可怜的娜娜,一个糖果都拿不掉,所以输出0

    由于输入数据较多,请谨慎使用cin/cout

    题意:n个数构成一个环,问最大子串和是多少。

    解法:首先你要学会不是环的最大子串和的O(n)DP算法。 普通的最大子串和的具体实现如下 用dp[i]来表示以该数a[i]结尾的最大子串和,转移为dp[i]=max(dp[i-1]+a[i],a[i]),这句表达式用自然语言说就是,考虑自己是跟着前一项还是新开一个子串,如果中断与前一项的联系会更优(即和更大),那么就让自己作为新的子串,否则就跟着前一项。 那么如果是环怎么办呢?我们可以发现其实答案只有两种,要么是不需要经过1,n的交界,这样只需当成普通的子串和就行了,如果经过1,n的交界呢?我们会发现等价于整个数列去掉中间的一块连续子串,要使剩下的最大,那么肯定要让去掉的子串和最小,怎么求最小子串和?把所有数取相反数再跑一次最大子串和即可。比较两个方案,输出最大的就是答案。

     1 #include <stdio.h>
     2 #include <string.h>
     3  
     4 int n,x[100005],dp[100005],sum;
     5  
     6 int max(int a,int b)
     7 {
     8     return a>b?a:b;
     9 }
    10  
    11 int solve()
    12 {
    13     int i,ma;
    14     for(i=0;i<n;i++)
    15     {
    16         if(i>0)
    17         {
    18             dp[i]=max(dp[i-1]+x[i],x[i]);
    19             if(ma<dp[i])
    20                 ma=dp[i];
    21         }
    22         else
    23         {
    24             dp[i]=max(dp[i],x[i]);
    25             ma=dp[i];
    26         }
    27     }
    28     return ma;
    29 }
    30  
    31 int main()
    32 {
    33     int t,i,ma,mi;
    34     while(scanf("%d",&t)!=EOF)
    35     {
    36         while(t--)
    37         {
    38             scanf("%d",&n);
    39             memset(dp,0,sizeof(dp));
    40             sum=0;
    41             for(i=0;i<n;i++)
    42             {
    43                 scanf("%d",&x[i]);
    44                 sum+=x[i];
    45             }
    46             ma=solve();             //求最大子串和
    47             memset(dp,0,sizeof(dp));
    48             for(i=0;i<n;i++)
    49             {
    50                 x[i]=-x[i];        //取反
    51             }
    52             mi=sum+solve();       //总和+最小子串和
    53             printf("%d\n",max(ma,mi));
    54         }
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    Qt使用第三方库3rdparty
    Qt5.5以来对Network的改进(包括对SSL的功能支持,HTTP的重定向等等)
    ddd
    C# ICSharpCode.SharpZipLib
    OWIN
    C#/.NET code
    ABP启动配置
    Oracle表空间及分区表
    Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用
    WebAPI使用多个xml文件生成帮助文档
  • 原文地址:https://www.cnblogs.com/weigx/p/4429010.html
Copyright © 2011-2022 走看看