zoukankan      html  css  js  c++  java
  • C

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

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

    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

    题目在于找最大环串和的,在于用DP[i]求最大子串和的方法的扩展。要找到最大环和的子串,要么存在于0~N的最大连续子串中,要是么超过边界N~0,则可以知道,在0~N之间存在一段最小子串和,去除这一段的最小子串和,便是最大子串和。这一题在于找出最大子串和和最小子串和,最大子串和的求法在于  ,DP[i]记录以i为结尾的子串的最大和, DP[i]=MAX(DP[i-1]+Num[i],Num[i]),,要求最小子串和的话,我们只需要对原本数据取相反数,在求一次最大子串和,便可以知道其1~N之间的最小子串和为多少,然后去掉这一段只需要(将原来的数据的总和+这一段最小子串和)既可。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <math.h>
     4 #include<stdio.h>
     5 #include<string.h>
     6 #include <stdlib.h>
     7 #define MAX(x,y) ((x)>(y)?(x):(y))
     8 #define MIN(x,y) ((x)<(y)?(x):(y))
     9 using namespace std;
    10 int N;
    11 int DP[1008600];
    12 int Num1[1008600];
    13 int Num2[1008600];
    14 int Search_DP(int Num[])
    15 {
    16     int Max=0;
    17     int DP[1008600];        /*DP[i]记录以i为结尾的子串的最大和*/
    18     DP[0]=Num[0];   
    19     for(int i=1;i<N;i++)
    20     {
    21         DP[i]=MAX(DP[i-1]+Num[i],Num[i]);/*DP[i]等于(DP[i-1]+Num[i]或者是Num[i])*/
    22         Max=MAX(DP[i],Max);     /*DP[i]等于(DP[i-1]+Num[i]或者是Num[i])*/
    23     }
    24     return Max;
    25 }
    26 int main()
    27 {
    28     int T,Max;
    29     int Max1;
    30     int Max2,sum;
    31     scanf("%d",&T);
    32     while(T--)
    33     {
    34         scanf("%d",&N);
    35         sum=0;
    36         for(int i=0;i<N;i++)
    37         {
    38             scanf("%d",&Num1[i]);
    39             sum+=Num1[i];
    40             Num2[i]=-Num1[i];   /*Num2[i]存Num1[i]原本数据的相反数*/
    41  
    42         }
    43         Max1=Search_DP(Num1);   /*用动态规划DP求最大子串和的*/
    44         Max2=Search_DP(Num2)+sum;   /*求Num1的最小子串和《=》对其相反数求最大子串和*/
    45         Max=MAX(Max1,Max2);
    46         printf("%d
    ",Max);
    47  
    48     }
    49 }
    View Code
    转载请备注:
    **************************************
    * 作者: Wurq
    * 博客: https://www.cnblogs.com/Wurq/
    * Gitee: https://gitee.com/wurq
    **************************************
  • 相关阅读:
    【转】 java中Class对象详解和类名.class, class.forName(), getClass()区别
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    107. Binary Tree Level Order Traversal II
    109. Convert Sorted List to Binary Search Tree
    108. Convert Sorted Array to Binary Search Tree
    110. Balanced Binary Tree
    STL容器迭代器失效问题讨论
    113. Path Sum II
    112. Path Sum
  • 原文地址:https://www.cnblogs.com/Wurq/p/4430006.html
Copyright © 2011-2022 走看看