zoukankan      html  css  js  c++  java
  • fzu 2136 取糖果 好几种方法解决。

    Problem 2136 取糖果

    Accept: 39    Submit: 101 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
     
    题意:略。
    思路:
       看一下最暴力的。
                                min (   a1,  a2,  a3,  a4 ,  a5   );
               min (  a1a2  a2a3   a3a4  a4a5 );
               min (  a1a2a3  a2a3a4  a3a4a5 );
                                min(   a1a2a3a4      a2a3a4a5) ;
              min(               a1a2a3a4a5    );
                               在每一行中,取  最大值的最小值。
        如果直接暴力会超时。
        比赛的时候,没做出来,后来别人说他用   单调栈来做。
      很多的题解有的用线段树,有的就直接剪枝过的。
     
        首先 处理 每一个a[i] 为最大值时,能管辖的范围。也就是说,f[i].l  f[i].r来保存管辖的位置。
        管辖的范围,有什么用呢?  仔细想一想。
        题意:每组数据输出n行,第i行表示lzs随机取连续的i个袋子时的最坏情况下能拿到的糖果数
        其实,就是在1---管辖范围,当前这个数字,有没有机会成为  取连续 i 个袋子时的  最小值的机会。
      
        线段树的怎么做呢?
        其实就是处理后面的内容。
        1.延迟更新每个数字的管辖范围。取最小值
        2.取得每个位置的最小值。   //这两步,直接枚举就可以了。
       
     
      
     1 #include<stdio.h>
     2 
     3 
     4 struct node
     5 {
     6     int l;
     7     int r;
     8 }f[100003];
     9 int a[100003];
    10 int ans[100003];
    11 
    12 int main()
    13 {
    14     int T,n;
    15     int i,j,k;
    16     while(scanf("%d",&T)>0)
    17     {
    18         while(T--)
    19         {
    20             scanf("%d",&n);
    21             for(i=1;i<=n;i++)
    22             {
    23                 scanf("%d",&a[i]);
    24                 ans[i]=1000000000;
    25             }
    26 
    27             for(i=1;i<=n;i++)
    28             {
    29                 for(j=i-1;j>=1;j--)
    30                 if(a[j]>a[i])break;
    31                 f[i].l=j+1;
    32 
    33                 for(j=i+1;j<=n;j++)
    34                 if(a[j]>a[i])break;
    35                 f[i].r=j-1;
    36             }
    37 
    38             for(i=1;i<=n;i++)
    39             {
    40                 k=f[i].r-f[i].l+1;
    41                 for(j=1;j<=k;j++)
    42                 if(ans[j]>a[i])
    43                 ans[j]=a[i];
    44             }
    45             for(i=1;i<=n;i++)
    46             printf("%d
    ",ans[i]);
    47         }
    48     }
    49     return 0;
    50 }
     
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3418892.html
Copyright © 2011-2022 走看看