zoukankan      html  css  js  c++  java
  • 子序列

    给定一个序列a[i],取出一段连续的子序列,使得子序列的和的绝对值最小。

    N<=10^6,a[i]<=10^9。

    sol:先求出前缀和,我们考虑到,任何一个子序列和的绝对值,都可以表示为|s[x]-s[y]|(x大于y),那么任何有一个|s[x]-s[y]|(x大于y),都对应一个子序列和的绝对值。所以,我们只要找出一组(x,y),使得|s[x]-s[y]|最小即可。故,可对前缀和排序后,依次比较|s[i]-s[i+1]的绝对值,从中选择最小的。

    如a[i]:2 8 -20 5 10

    s[i]:0 2 10 -10 -5 5(s[0]=0要参与进来排序和后续比较运算)

    排序后s[i]:-10 -5 0 2 5 10

    |s[i]-s[i+1|]:5 5 2 3 5 ,最小2为本题答案。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #define INF 1000005
     6 using namespace std;
     7 int num[INF],sum[INF];
     8 int main()
     9 {
    10     int N;
    11     scanf("%d",&N);
    12     for(int i=1;i<=N;i++)
    13         scanf("%d",&num[i]);
    14     sum[0]=0;
    15     for (int i=1;i<=N;i++)
    16         sum[i]+=sum[i-1]+num[i];
    17     sort(sum,sum+N+1);  //注意,这里s[0]要参与排序和进行后续的比较运算。      
    18     int minx=INF;
    19     for(int i=0;i<N;i++)
    20         if(abs(sum[i]-sum[i+1])<minx) minx=abs(sum[i]-sum[i+1]);
    21     printf("%d
    ",minx);    
    22     return 0;
    23 }
  • 相关阅读:
    第十二周作业
    十一周作业
    第十周作业
    第九周作业
    2019年春第八周作业
    第五周课程总结&实验报告(三)
    第四周课程总结&实验报告(二)
    第三周课程总结&实验报告(一)
    第二周课程总结
    2019春总结作业
  • 原文地址:https://www.cnblogs.com/cutepota/p/12120567.html
Copyright © 2011-2022 走看看