• fzu 2136 链表


    Problem 2136 取糖果

    Accept: 89    Submit: 221
    Time Limit: 1000 mSec    Memory Limit : 32768 KB

    Problem Description

    有N个袋子放成一排,每个袋子里有一定数量的糖果,lzs会随机选择连续的几个袋子,然后拿走这些袋子中包含最多糖果的袋子。现问你,在选择x个袋子的情况下,lzs最坏情况下,也就是最少会拿到多少个糖果?对于x取值为1到n都分别输出答案。

    Input

    第一行一个整数T,表示有T组数据。

    每组数据先输入一行一个整数N(1<=N<=100000),表示袋子数,接下来一行输入N个正整数,输入的第i个数表示第i个袋子所装的糖果数。

    Output

    每组数据输出n行,第i行表示lzs随机取连续的i个袋子时的最坏情况下能拿到的糖果数。

    Sample Input

    1 5 1 3 2 4 5

    Sample Output

    1 3 3 4 5


     
     
    在众神题解的关照下,终于想通且A了。
    算法:①按元素值从小到大依次求出每个元素所在的连续最长区间长度,使该元素在这个区间内最大,②然后因为是枚举每个元素的最长区间长度的,需要ans[len]=min(ans[len], ans[len+1]).
    第②步的正确性?
    1.当len=1时,则ans[1] = min(e[i]),i从0,到n-1,e[i]为第i个元素;
    2.当len=n时,则ans[n] = max(e[i]), 同上;
    3.当len取其它值设为k,若某个元素可达区间长度为bk,且bk>k, 则该元素一定是某些(个)区间长度为k的区间内最大值, 所以ans[k] =min(ans[i]) 对所有大于k的i。
     
    ACCEPTED:
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn = 111111;
    const int inf = 1 << 30;
    int lft[maxn], rit[maxn];
    int e[maxn], ind[maxn], n;
    int lcnt[maxn], rcnt[maxn];             //模拟双向链表
    int ans[maxn];
    
    bool cmp(const int a, const int b){
        return e[a] < e[b];
    }
    
    int main(){
        int t;
        scanf(" %d", &t);
        while(t--){
            scanf(" %d", &n);
            for(int i=0; i<n; i++){
                scanf(" %d", e+i);
                ind[i]=i;                   
                //左右元素下标
                lft[i] = i-1;   rit[i] = i+1;
                //计算连续区间长度,左边,右边
                lcnt[i] = rcnt[i] = 0;
                ans[i+1] = inf;
            }
            //升序排,第i大的元素在ind[i]
            sort(ind, ind+n, cmp);
            for(int i=0; i<n; i++){
                int tind = ind[i], tlen = rcnt[tind] + lcnt[tind] + 1;
                ans[tlen] = min(ans[tlen], e[tind]);
                //删除e[i], 更新左右元素区间长度
                if(lft[tind]>-1) rcnt[lft[tind]]+=(rcnt[tind]+1), rit[lft[tind]] = rit[tind];
                if(rit[tind]<n) lcnt[rit[tind]]+=(lcnt[tind]+1), lft[rit[tind]] = lft[tind];
            }
            //...
            for(int i=n-1; i; i--) ans[i]=min(ans[i], ans[i+1]);
            for(int i=1; i<n+1; i++) printf("%d
    ", ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    学习笔记datatablexml转换
    立即执行函数
    MySQL基操—1.Linux下安装(CentOS6/7yum、rpm、tar)
    Linux1.11.shell(环境变量配置文件)
    三国HR评估报告
    毕业5年后拉开差距的原因
    职业的选择
    WPF图片的缩放节省内存
    .asmx支持post请求或者get请求调用
    ionic3遇到的刷新页面服务器关闭的问题
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3469834.html
Copyright © 2020-2023  润新知