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 }

 

 

你可能感兴趣的:(方法)