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\n",ans[i]);
47         }
48     }
49     return 0;
50 }

 

 
posted @ 2013-11-12 09:16  芷水  阅读(386)  评论(2编辑  收藏  举报