zoukankan      html  css  js  c++  java
  • hdu 3415 Max Sum of MaxKsubsequence

      做dp遇到了单调队列优化的问题,所以便又跑来学这东西来了,单调队列,单调栈。

      最近一直在被老师,被同学糗,吼吼。> <

      题意:给定一个长度为n的环形序列,让你从中找出一个k长的子序列,使得这段序列的和是所有k长子序列中和最大的那个,输出和,并输出得到这个和时的起始位置跟终止位置。

      思路:因为还要记录起始位置跟终止位置,所以很显然队列结点还需要记录下标。我们用一个单调减队列来维护到当前下标时,前面sum的最小值,当然还需要head++使得长度控制在k的范围内。循环判断更新最大值,并记录相应下标就可以了。

    View Code
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    const int maxn=100000+5;
    
    int a[maxn],sum[maxn<<1],head,tail,n,k,st,ed,ans;
    struct node
    {
        int val;
        int tag;
        node(int v=0,int t=0):val(v),tag(t){}
    }q[maxn<<1];
    
    void data_in()
    {
        memset(sum,0,sizeof(sum));
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=n+1;i<=n+k;i++)
            sum[i]=sum[i-1]+a[i-n];
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d",&n,&k);
            data_in();
            head=1;tail=1;
            q[tail]=node(0,1);
            st=ed=1;
            ans=sum[1];
            for(int i=2;i<=n+k;i++)
            {
                while(head<=tail&&q[tail].val>sum[i-1]) tail--;
                q[++tail]=node(sum[i-1],i);
                while(head<=tail&&q[head].tag<=i-k) head++;
                int tmp=sum[i]-q[head].val;
                if(tmp>ans)
                {
                    ans=tmp;
                    st=q[head].tag;
                    ed=i;
                }
            }
            if(st>n) st-=n;
            if(ed>n) ed-=n;
            printf("%d %d %d\n",ans,st,ed);
        }
        return 0;
    }
  • 相关阅读:
    数组小练习
    数组
    利用数组进行排序
    继承练习
    黄金分割点
    百万富翁-循环练习
    SelectedIndexChanged事件, SelectedValueChanged事件和SelectionChangeCommitted事件的区别及应用——c#
    进制转换以及与字符串之间转换——c#
    文件中的类都不能进行设计,因此未能为该文件显示设计器
    winfrom自绘窗体边框——c#
  • 原文地址:https://www.cnblogs.com/RainingDays/p/2971783.html
Copyright © 2011-2022 走看看