Deque

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 731    Accepted Submission(s): 236

Problem Description
Today, the teacher gave Alice extra homework for the girl weren't attentive in his class. It's hard, and Alice is going to turn to you for help.

The teacher gave Alice a sequence of number(named A) and a deque. The sequence exactly contains N integers. A deque is such a queue, that one is able to push or pop the element at its front end or rear end. Alice was asked to take out the elements from the sequence in order(from A_1 to A_N), and decide to push it to the front or rear of the deque, or drop it directly. At any moment, Alice is allowed to pop the elements on the both ends of the deque. The only limit is, that the elements in the deque should be non-decreasing.

Alice's task is to find a way to push as many elements as possible into the deque. You, the greatest programmer, are required to reclaim the little girl from despair.

 
Input
The first line is an integer T(1≤T≤10) indicating the number of test cases.

For each case, the first line is the length of sequence N(1≤N≤100000).

The following line contains N integers A
1,A
2,…,A
N.

 
Output
For each test case, output one integer indicating the maximum length of the deque.
 
Sample Input
3
7
1 2 3 4 5 6 7
5
4 3 2 1 5
5
5 4 1 2 3
 
Sample Output
7
5
3
 
Source
 
Recommend
liuyiding
 

我直接附上标准题解吧。。当时是看出这是最长下降跟最长上升序列的求和的,只是因为没相处nlogn算法,最终没有做出来。 今天终于AC掉了。 刚开始考虑的时候,还是没有考虑到

5

5 5 5 5 5 这种需要过滤掉重复的方法,导致WA了很多次,后来多开了一个数组保留才AC掉。

标准题解是:

Problem E. Deque考虑题目的一个简化版本:使双端队列单调上升。对于序列 A 和队列 Q,找到队列中最早出现的数字Ax,则Ax将 Q 分成的两个部分分别是原序列中以Ax开始的最长上升和最长下降序列,答案即为这两者之和的最大值。而对于本题,由于存在相同元素,所以只要找到以Ax为起点的最长不下降序列和最长不上升序列的和,然后减去两个里面出现Ax 次数的最小值即可。

我的代码是:

/*
* @author ipqhjjybj
* @date 20130723
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAXN 100005
#define clr(x,k) memset((x),(k),sizeof(x))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
int n;
int a[MAXN];
int d_p[MAXN]; //存储递减序列的数字
int d_f[MAXN];
int n_d_f[MAXN];//相同数字出现次数
int i_p[MAXN]; //存储递增序列的数字
int i_f[MAXN];
int n_i_f[MAXN];//相同数字出现次数
int find_dec(int l,int r,int x){
int i=l,j=r,mid;
while(i<=j){
mid=(i+j)>>1;
if(d_p[mid]<=x) i=mid+1;
else j=mid-1;
}return i;
}
int find_inc(int l,int r,int x){
int i = l,j=r,mid;
while(i<=j){
mid=(i+j)>>1;
if(i_p[mid]>=x) i=mid+1;
else j=mid-1;
}return i;
}
int main(){
//freopen("1005.in","r",stdin);
int z;
scanf("%d",&z);
while(z--){
clr(n_i_f,0),clr(n_d_f,0);
scanf("%d",&n);
for(int i = 1;i <= n;i++)
scanf("%d",&a[i]);
int ans=1;
int d_ans=1;
d_p[1]=a[n];
d_f[n]=1;
n_d_f[1]=1;
int i_ans=1;
i_p[1]=a[n];
i_f[n]=1;
n_i_f[1]=1;
for(int i=n-1;i>0;i--){
int t1=find_dec(1,d_ans,a[i]);
if(t1>d_ans)d_ans++;
d_p[t1]=a[i];
n_d_f[t1]=(t1>1&&d_p[t1-1]==a[i])?n_d_f[t1-1]+1:1;
d_f[i]=t1;
int t2=find_inc(1,i_ans,a[i]);
if(t2>i_ans)i_ans++;
i_p[t2]=a[i];
n_i_f[t2]=(t2>1&&i_p[t2-1]==a[i])?n_i_f[t2-1]+1:1;
i_f[i]=t2; //printf("m_t1=%d m_t2=%d\n",m_t1,m_t2);
int temp = t1+t2-min(n_d_f[t1],n_i_f[t2]);
ans = max(ans,temp);
}
printf("%d\n",ans);
}
return 0;
}

325MS过掉。。

附上标准程序

#include "iostream"
#include "cstring"
#include "cstdio"
#include "vector"
#include "algorithm"
#include "map"
using namespace std;
const int N = 100010;
int a[N];
int num_up[N],num_down[N];
int dp_up[N],dp_down[N];
int n;
void getdp(int dp[],int num[])
{
dp[n]=1;
vector<int> v;
v.push_back(a[n]);
vector<int>::iterator iter;
for(int i=n-1;i>=1;i--){
int sz=v.size();
if(a[i]>v[sz-1]){
v.push_back(a[i]);
dp[i]=sz+1;
num[i]=1;
}else if(a[i]==v[sz-1]){
iter=upper_bound(v.begin(),v.end(),a[i]);
dp[i]=iter-v.begin()+1;
v.push_back(a[i]);
pair<vector<int>::iterator,vector<int>::iterator> bounds;
bounds=equal_range(v.begin(),v.end(),a[i]);
num[i]=bounds.second-bounds.first;
}else{
iter=upper_bound(v.begin(),v.end(),a[i]);
dp[i]=iter-v.begin()+1;
*iter=a[i];
pair<vector<int>::iterator,vector<int>::iterator> bounds;
bounds=equal_range(v.begin(),v.end(),a[i]);
num[i]=bounds.second-bounds.first;
}
}
}
void debug(int a[])
{
for(int i=1;i<=n;i++){
printf("%d ",a[i]);
}
printf("\n");
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--){
int ans=0;
scanf("%d",&n);
map<int,int> mp;
mp.clear();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
getdp(dp_up,num_up);
for(int i=1;i<=n;i++){
a[i]=-a[i];
}
getdp(dp_down,num_down);
for(int i=1;i<=n;i++){
mp[a[i]]++;
ans=max(ans,dp_down[i]+dp_up[i]-min(num_up[i],num_down[i]));
}
printf("%d\n",ans);
}
return 0;
}

标准程序用了986MS。。。可能我的程序优化的还好点吧。。。

总而言之是水平不够。。当时没想出nlogn算法。。

多校联合练习赛1 Problem1005 Deque LIS+LDS 再加一系列优化的更多相关文章

  1. HDU 多校联合练习赛2 Warm up 2 二分图匹配

    Warm up 2 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  2. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  3. 2016暑假多校联合---Windows 10

    2016暑假多校联合---Windows 10(HDU:5802) Problem Description Long long ago, there was an old monk living on ...

  4. 2016暑假多校联合---Substring(后缀数组)

    2016暑假多校联合---Substring Problem Description ?? is practicing his program skill, and now he is given a ...

  5. 2016暑假多校联合---To My Girlfriend

    2016暑假多校联合---To My Girlfriend Problem Description Dear Guo I never forget the moment I met with you. ...

  6. 2016暑假多校联合---A Simple Chess

    2016暑假多校联合---A Simple Chess   Problem Description There is a n×m board, a chess want to go to the po ...

  7. HDU 5792---2016暑假多校联合---World is Exploding

    2016暑假多校联合---World is Exploding Problem Description Given a sequence A with length n,count how many ...

  8. 2016暑假多校联合---Another Meaning

    2016暑假多校联合---Another Meaning Problem Description As is known to all, in many cases, a word has two m ...

  9. hdu 5288||2015多校联合第一场1001题

    pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...

随机推荐

  1. 深入理解MFC子类化

    子类化,通俗来讲就是用自己的窗口处理函数来处理特定消息,并将自己其他消息还给标准(默认)窗口处理函数.在SDK中,通过SetWindowLong来指定一个自定义窗口处理函数:SetWindowLong ...

  2. SQLServer查看和解决死锁的方法

    http://luohonghong.blog.163.com/blog/static/78312058201142411533316/ SQLServer查看和解决死锁的方法 2011-05-24 ...

  3. poI地址纠偏查询存储过程理解

    1.POI存储过程查询 服务器类型:PostgreSQL function name 函数名字 address_parse_no_save(lon float8, lat float8) DECLAR ...

  4. C指针

    1,每行最大长度,处理的最大列号; preprocessor directives,preprocessor,预处理器读入源代码,根据预处理指令对其进行修改,把修改后 的源代码递交给编译器; 预处理器 ...

  5. poj1966Cable TV Network(无向图最小点割集 ISAP+邻接矩阵)

    题目请戳这里 邻接表的ISAP被卡了一天...TLE....终于被卡了...好忧桑啊啊啊... 题目大意:给一张无向图,求最少去掉几个点使图不连通. 题目分析:求无向图的点连通度,拆点建图跑最大流.具 ...

  6. fafu 1568 Matrix(二分匹配+二分)

    Description:   You are given a matrix which <= n <= m <= ). You are supposed to choose n el ...

  7. Storages and virtual servers

    1. IBM Storages: SONAS,V7k,V7ku,SVC,XIV 存储设备都安装了个性化定制的Linux系统,来完成不同的服务,这几台存储设备使用原理都是类似的,以SONAS (Scal ...

  8. 反对抄袭 正解spring的@Autowired 不要相信网上的错误版本

    首先,最重要的, @Autowired的就是用来来消除 set ,get方法. 有些介绍,如著名的马士兵,说要在set方法上进行注入.我当时就看不明白了,既然只取消了一个GET,这个@Autowire ...

  9. OpenCms创建站点过程图解——献给OpenCms的刚開始学习的人们

    非常多人都听说了OpenCms,知道了它的强大,索性的下载安装了,最终见到了久违OpenCms,看到了它简洁的界面,欣喜过后却不免一脸茫然,这个东西怎么用,我怎么用它来建站,从哪開始,无从下手,找资料 ...

  10. CSS基础知识之position

    最近在慕课网学习了 网页布局基础 和 固定层效果 ,都是由声音甜美的 婧享人生 老师所录制,视频详细讲解了CSS中position的用法,在此把学习笔记分享给大家. CSS定位机制 标准文档流(Nor ...