首页 > 其他 > 详细

hdu 4604 Deque

时间:2014-03-06 20:12:18      阅读:432      评论:0      收藏:0      [点我收藏+]

题意:给出N个数A_1 to A_N和一个双向队列(两头都可以push),按顺序从N个数中取数,取出的数要么丢弃,要么从队列一端压入。队列中的数要求是不降。求最多能放入多少个数。

 

思路:由于A_1 to A_N是按顺序取,因此可以从右往左求最长不增子序列a[i]和最长不降子序列b[i],然后枚举每个数作为第一个放入的元素,得到a[i]+b[i]-1。但是这还不是答案,因为两个序列是不降和不增,虽然从同一个数开始递增递减,类似 4 4 3 2 1 5 这样的数列,第二个4就计算重复了,所以要处理一下,减去重复的数。

求最长不增序列和最长不降序列要用O(nlogn算法)。

 

 

bubuko.com,布布扣
  1 #include <cstdio>
  2 #include <cstring>
  3 #define N 100005
  4 
  5 int d[N], a[N], b[N], n, aa[N], bb[N], t1[N], t2[N];
  6 
  7 int bs(int x, int len)
  8 {
  9     int l = 1, r = len, mid;
 10     while(l<r)
 11     {
 12         mid = (l + r) / 2;
 13         if(x<a[mid]) r = mid;
 14         else if(x>=a[mid]) l = mid + 1;
 15     }
 16     return l;
 17 }
 18 
 19 int bs2(int x, int len)
 20 {
 21     int l = 1, r = len, mid;
 22     while(l<r)
 23     {
 24         mid = (l + r) / 2;
 25         if(x>b[mid]) r = mid;
 26         else if(x<=b[mid]) l = mid + 1;
 27     }
 28     return l;
 29 }
 30 
 31 int main()
 32 {
 33     int t;
 34     scanf("%d",&t);
 35     while(t--)
 36     {
 37         memset(t1, 0sizeof(t1));
 38         memset(t2, 0sizeof(t2));
 39         scanf("%d",&n);
 40         for(int i=1; i<=n; i++)
 41             scanf("%d",&d[i]);
 42         int len1 = 1;
 43         a[1] = d[n];
 44         aa[n] = 1;
 45         for(int i=n-1; i>=1; i--)
 46         {
 47             if(d[i]>=a[len1])
 48             {
 49                 a[++len1] = d[i];
 50                 aa[i] = len1;
 51             }
 52             else
 53             {
 54                 int pos = bs(d[i],len1);
 55                 aa[i] = pos; //前i个数的最长不降子序列长度为pos
 56                 a[pos] = d[i];
 57             }
 58         }
 59 
 60         int len2 = 1;
 61         b[1] = d[n];
 62         bb[n] = 1;
 63         for(int i=n-1; i>=1; i--)
 64         {
 65             if(d[i]<=b[len2])
 66             {
 67                 //printf("b:%d\n",i);
 68                 b[++len2] = d[i];
 69                 bb[i] = len2;
 70             }
 71             else
 72             {
 73                 int pos = bs2(d[i],len2);
 74                 bb[i] = pos;
 75                 b[pos] = d[i];
 76             }
 77         }
 78         int ans = 0, aid = -1;
 79         for(int i=1; i<=n; i++)
 80         {
 81             int tmp = aa[i] + bb[i] - 1;
 82             if(ans<tmp)
 83             {
 84                 ans = tmp;
 85                 aid = i;
 86             }
 87         }
 88 
 89         for(int i=aid+1; i<=n; i++)
 90         {
 91             if(d[i]==d[aid])
 92             {
 93                 t1[aa[aid]-aa[i]]++;
 94                 t2[bb[aid]-bb[i]]++;
 95             }
 96         }
 97         for(int i=1; i<=n; i++)
 98         {
 99             if(t1[i]==1 && t2[i]==1) ans--;
100         }
101         printf("%d\n",ans);
102     }
103     return 0;
104 }
View Code

hdu 4604 Deque,布布扣,bubuko.com

hdu 4604 Deque

原文:http://www.cnblogs.com/byluoluo/p/3584227.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!