• 最大字段和


     
    //常州大学新生寒假训练会试
    /*
    
    题目描述 
    常州大学组织了新生寒假训练一共N天,每天训练可以获得的训练效果是Ei。但是如果连续训练超过K天,萌新们会受不了而被劝退。
    现在负责人想知道,如何安排能保证萌新不会被劝退并且能获得最大的训练效果。
    输入描述:
    第一行:两个用空格隔开的整数:N和K,1≤N≤100000,1≤K≤N
    第二行到N+1行:第i+1行有一个整数,表示第N天的训练效果是Ei,(0 <= Ei <= 1,000,000,000)
    输出描述:
    第一行:单个整数,表示最大的能力之和
    示例1
    输入
    复制
    5 2 
    1
    2
    3
    4 
    5
    输出
    复制
    12
    说明
    (除了第三天以外每天都在训练,总训练效果为1+2+4+5=12)
    备注:
    1≤n≤100,000
    */
    
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <deque>
    using namespace std;
    #define  ll long long 
    #define  N 100009
    #define  gep(i,a,b)   for(int  i=a;i<=b;i++)
    #define  gepp(i,a,b)  for(int  i=a;i>=b;i--)
    #define  gep1(i,a,b)  for(ll i=a;i<=b;i++)
    #define  gepp1(i,a,b) for(ll i=a;i>=b;i--)    
    #define  mem(a,b)  memset(a,b,sizeof(a))
    int  n,k,st,ed;
    ll a[N],q[N],dp[N];
    //dp[i]  :第i天不训练带来的最小损失(逆向思维)
    int  main()
    {
        scanf("%d%d",&n,&k);
        ll sum=0;
        gep(i,1,n)
        {
            scanf("%lld",&a[i]);
            sum+=a[i];
        }
        //维护一个单调队列
        gep(i,1,n)
        {
            
            while(st<=ed&&dp[q[ed]]>dp[i-1])  ed--;      
            while(q[st]<i-k-1) st++;
            q[++ed]=i-1;
            dp[i]=dp[q[st]]+a[i];//队首最小
        }
        ll ans=0;
        //例如  dp[4]=a[4]+a[1],dp[5]=a[5]+a[2]
        gep(i,n-k,n){//必须从n-k开始,才能保证天数不超过k天
            ans=max(ans,sum-dp[i]);
        }
        printf("%lld
    ",ans);
        return  0;
    }

    最大子序和

    题目限制

    时间限制 内存限制 评测方式 题目来源
    1000ms 131072KiB 标准比较器 Local

    题目描述

    输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大。

    例如 1,-3,5,1,-2,3

    当m=4时,S=5+1-2+3=7
    当m=2或m=3时,S=5+1=6

    输入格式

    第一行两个数n,m
    第二行有n个数,要求在n个数找到最大子序和

    输出格式

    一个数,数出他们的最大子序和

    提示

    数据范围:
    100%满足n,m<=300000

    样例数据

    输入样例 #1输出样例 #1
    6 4
    1 -3 5 1 -2 3
    7
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <string>
     7 #include <deque>
     8 using namespace std;
     9 #define  ll long long 
    10 #define  N 300009
    11 const ll inf=9e18;
    12 #define  gep(i,a,b)   for(int  i=a;i<=b;i++)
    13 #define  gepp(i,a,b)  for(int  i=a;i>=b;i--)
    14 #define  gep1(i,a,b)  for(ll i=a;i<=b;i++)
    15 #define  gepp1(i,a,b) for(ll i=a;i>=b;i--)    
    16 #define  mem(a,b)  memset(a,b,sizeof(a))
    17 int  n,k,st,ed;
    18 ll a[N],q[N],dp[N],sum[N];
    19 int  main()
    20 {
    21     scanf("%d%d",&n,&k);
    22     gep(i,1,n)
    23     {
    24         scanf("%lld",&a[i]);
    25         sum[i]=sum[i-1]+a[i];
    26     }
    27     //维护一个单调队列
    28     gep(i,1,n)
    29     {       
    30         while(st<=ed&&sum[q[ed]]>sum[i-1])  ed--;
    31         while(st<=ed&&q[st]<i-k) st++;//为i服务的
    32         q[++ed]=i-1;//要非空区间
    33         dp[i]=sum[i]-sum[q[st]];//队首最小
    34     }
    35     ll ans=-inf;
    36     gep(i,1,n){
    37         ans=max(ans,dp[i]);
    38     }
    39     printf("%lld
    ",ans);
    40     return  0;
    41 }

    /HDU  3415

    Max Sum of Max-K-sub-sequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9408    Accepted Submission(s): 3472


    Problem Description
    Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
    Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
     
    Input
    The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. 
    Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
     
    Output
    For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
     
    Sample Input
    4 6 3 6 -1 2 -6 5 -5 6 4 6 -1 2 -6 5 -5 6 3 -1 2 -6 5 -5 6 6 6 -1 -1 -1 -1 -1 -1
     
    Sample Output
    7 1 3 7 1 3 7 6 2 -1 1 1
     
    Author
    shǎ崽@HDU
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  3423 3417 3418 3419 3421 
     
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <string>
     7 #include <deque>
     8 #include <set>
     9 #include <queue>
    10 using namespace std;
    11 #define  ll long long 
    12 #define  N 200009
    13 #define  gep(i,a,b)   for(int  i=a;i<=b;i++)
    14 #define  gepp(i,a,b)  for(int  i=a;i>=b;i--)
    15 #define  gep1(i,a,b)  for(ll i=a;i<=b;i++)
    16 #define  gepp1(i,a,b) for(ll i=a;i>=b;i--)    
    17 #define  mem(a,b)  memset(a,b,sizeof(a))
    18 #define  P  pair<int,int>u+
    19 const ll inf=9e18;
    20 int  n,k,st,ed;
    21 ll a[N],q[N],sum[N];
    22 int t;
    23 int  main()
    24 {
    25     scanf("%d",&t);
    26     while(t--){
    27     scanf("%d%d",&n,&k);
    28     sum[0]=0;//不用mem(sum,0)
    29     gep(i,1,n)
    30     {
    31         scanf("%lld",&a[i]);
    32         sum[i]=sum[i-1]+a[i];
    33     }   
    34     gep(i,n+1,n+k-1)//环状到n+k-1就可以了
    35     {
    36         sum[i]=sum[i-1]+a[i-n];
    37     }
    38     //不按照上面求前缀和会超时
    39     ll ans=-inf;
    40     ll l,r;
    41     st=0;
    42     ed=0;
    43     mem(q,0);
    44     //上面三行代码不能少
    45     gep1(i,1,n+k-1)
    46     {        
    47         
    48         while(st<=ed&&sum[q[ed]]>sum[i-1])  ed--;
    49         while(st<=ed&&q[st]<i-k) st++;    
    50         q[++ed]=i-1; 
    51         if(ans<sum[i]-sum[q[st]]){
    52         ans=sum[i]-sum[q[st]];
    53         l=q[st]+1;
    54         r=i>n?i%n:i;//r可能大于n
    55         //当出现dp[i]都是最大值时,一定是i小的符合条件
    56         // 0 2 3 0                         
    57         }        
    58     }
    59     printf("%lld %lld %lld
    ",ans,l,r);
    60     }
    61     return  0;
    62 }

    //HDU    6444

    Neko's loop

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1420    Accepted Submission(s): 328


    Problem Description
    Neko has a loop of size n.
    The loop has a happy value ai on the ith(0in1) grid. 
    Neko likes to jump on the loop.She can start at anywhere. If she stands at ith grid, she will get ai happy value, and she can spend one unit energy to go to ((i+k)modn)th grid. If she has already visited this grid, she can get happy value again. Neko can choose jump to next grid if she has energy or end at anywhere. 
    Neko has m unit energies and she wants to achieve at least s happy value.
    How much happy value does she need at least before she jumps so that she can get at least s happy value? Please note that the happy value which neko has is a non-negative number initially, but it can become negative number when jumping.
     
    Input
    The first line contains only one integer T(T50), which indicates the number of test cases. 
    For each test case, the first line contains four integers n,s,m,k(1n104,1s1018,1m109,1kn).
    The next line contains n integers, the ith integer is ai1(109ai1109)
     
    Output
    For each test case, output one line "Case #x: y", where x is the case number (starting from 1) and y is the answer.
     
    Sample Input
    2 3 10 5 2 3 2 1 5 20 6 3 2 3 2 1 5
     
    Sample Output
    Case #1: 0 Case #2: 2
     
    Source
     
    Recommend
    chendu   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <utility>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <stack>
    10 using namespace std;
    11 #define max(x,y) x>=y?x:y
    12 #define lowbit(x) x&(-x)
    13 #define ll long long 
    14 #define ph  push_back
    15 #define   N 100007//因为后面有3*n ,那么最好N 要大与3*n
    16 const ll inf =9e18;
    17 int t;
    18 ll n,m,s,k,a[N],q[N],sum[N];
    19 vector<ll>ve[N];
    20 bool vis[N];
    21 ll solve(int x,int n,ll m){//m  : ll
    22 ll ans=0;
    23 // ll q[N],sum[N]:是错的,因为局部变量必须初始化
    24 for(int i=0;i<=3*n;i++){
    25     sum[i]=0;
    26     q[i]=0;
    27 }
    28 for(int i=1;i<=n;i++){
    29     sum[i]=sum[i+n]=sum[i+2*n]=ve[x][i-1];
    30 }    
    31 for(int i=1;i<=3*n;i++) sum[i]=sum[i-1]+sum[i];//要加到3*n
    32 int st=0,ed=0;
    33 for(int i=1;i<=3*n;i++)//n+ans2(ans2<=2*n)<=3*n
    34 {
    35     while(st<=ed&&sum[i-1]<sum[q[ed]]) ed--;
    36     while(st<=ed&&i-q[st]>m) st++;//i-q[st]>m 
    37     q[++ed]=i-1;//加的是i-1
    38     ans=max(ans,sum[i]-sum[q[st]]);
    39 }
    40 return ans;
    41 }
    42 
    43 int main(){
    44     scanf("%d",&t);
    45     for(int tt=1;tt<=t;tt++)
    46     {
    47         scanf("%lld%lld%lld%lld",&n,&s,&m,&k);
    48         for(int i=0;i<N;i++) {
    49             vis[i]=0;
    50             ve[i].clear();//每次都要清空
    51         }
    52         for(int i=0;i<n;i++){
    53             scanf("%lld",&a[i]);
    54         }
    55         int cnt=0;
    56         for(int i=0;i<n;i++)
    57         {
    58             if(!vis[i])//不然cnt 会不断加
    59             {
    60                 for(int j=i;!vis[j];j=(j+k)%n)//只要在遇到vis[j]==1就该结束循环了
    61                 {
    62                     vis[j]=1;
    63                     ve[cnt].ph(a[j]);
    64                 }
    65                 cnt++;                
    66             }
    67         }
    68         ll ans=-inf;
    69         for(int i=0;i<cnt;i++)
    70         {
    71             ll tmp=0;
    72             int l=ve[i].size();
    73             for(int j=0;j<l;j++) tmp+=ve[i][j];//刚开始int i
    74             ll res=solve(i,l,m);//如果tmp<0,那么跑个不大于m的……即可
    75             ans=max(ans,res);    
    76             if(tmp<0) continue;
    77             ll ans1=m/l;
    78             ll ans2=m%l;
    79             if(ans1>=1) {//只要后面还有循环节,且>0就可以全取了
    80                 ans2+=l;//那么最后一个循环要特判
    81             }
    82             /*
    83             例如 :
    84             5 1000 5 1
    85             1 1 -1 -1 1
    86             正确的为 997,不是999
    87             */
    88             tmp=tmp*(max(ans1-1,0ll));//ans1==1可能
    89             res=max(res,tmp+solve(i,l,ans2));
    90             ans=max(ans,res);
    91         }
    92         ans=max(0ll,s-ans);
    93         printf("Case #%d: %lld
    ",tt,ans);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    VS2010+C#写的3D的Android游戏开源咯....不来看别后悔哦。
    把XAML放在服务端,即改即现.....
    TagSL框架设计(1)先来点简介
    OpenMP模式下多线程文件操作 (转)
    VS获取工程版本信息
    OpenMP模式下多线程文件操作(五)
    简单建立DLL和使用DLL
    OpenMP模式下多线程文件操作(三)
    OpenMP模式下多线程文件操作(四)
    【转】VC2008在工具栏Toolbar里添加XP风格spin box control控件
  • 原文地址:https://www.cnblogs.com/tingtin/p/9317936.html
Copyright © 2020-2023  润新知