多校联合练习赛1 Problem1005 Deque LIS+LDS 再加一系列优化
Deque
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 731 Accepted Submission(s): 236
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.
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.
7
1 2 3 4 5 6 7
5
4 3 2 1 5
5
5 4 1 2 3
5
3
我直接附上标准题解吧。。当时是看出这是最长下降跟最长上升序列的求和的,只是因为没相处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 再加一系列优化的更多相关文章
- HDU 多校联合练习赛2 Warm up 2 二分图匹配
Warm up 2 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- 2016暑假多校联合---Windows 10
2016暑假多校联合---Windows 10(HDU:5802) Problem Description Long long ago, there was an old monk living on ...
- 2016暑假多校联合---Substring(后缀数组)
2016暑假多校联合---Substring Problem Description ?? is practicing his program skill, and now he is given a ...
- 2016暑假多校联合---To My Girlfriend
2016暑假多校联合---To My Girlfriend Problem Description Dear Guo I never forget the moment I met with you. ...
- 2016暑假多校联合---A Simple Chess
2016暑假多校联合---A Simple Chess Problem Description There is a n×m board, a chess want to go to the po ...
- HDU 5792---2016暑假多校联合---World is Exploding
2016暑假多校联合---World is Exploding Problem Description Given a sequence A with length n,count how many ...
- 2016暑假多校联合---Another Meaning
2016暑假多校联合---Another Meaning Problem Description As is known to all, in many cases, a word has two m ...
- hdu 5288||2015多校联合第一场1001题
pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...
随机推荐
- 在C#中调用Win32函数EnumWindows枚举所有窗口。
原文 http://www.cnblogs.com/mfm11111/archive/2009/06/30/1514322.html 开发旺旺群发软件,难点及重要技术点分析(一) 一. ...
- Linux脚本练习
例1:写一个脚本,利用循环和continue关键字,计算100以内能被3整除的数之和 运行结果: 例2: 写一个脚本,利用循环和continue关键字,计算100以内能被3整除的数之和 运行结果: 例 ...
- C指针
1,每行最大长度,处理的最大列号; preprocessor directives,preprocessor,预处理器读入源代码,根据预处理指令对其进行修改,把修改后 的源代码递交给编译器; 预处理器 ...
- mysql中limit用法误区
之前一直用oracle,在分页的时候用rownumber,转换到mysql上之后,用limit做分页: 在做某个业务的时候,需要先将数据排序,再分页,在给limit上参数的时候沿用了oracle的ro ...
- 变形课(dfs)
变形课 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total Submissi ...
- poj 2186 (强连通缩点)
题意:有N只奶牛,奶牛有自己认为最受欢迎的奶牛.奶牛们的这种“认为”是单向可传递的,当A认为B最受欢迎(B不一定认为A最受欢迎),且B认为C最受欢迎时,A一定也认为C最受欢迎.现在给出M对这样的“认为 ...
- android xml布局文件属性说明
android xml布局文件属性说明 [摘]android xml布局文件属性说明 LinearLayout和RelativeLayout 共有属性:java代码中通过btn1关联次控件androi ...
- Parallels destop8 无法创建bootcamp虚拟机
创建基于Boot Camp的虚拟机时弹出“PRL_ERR_DISK_FILE_OPEN_ERROR (0x80021014)”错误提示,由于Mac系统权限错误或Boot Camp内Windows系统权 ...
- C# Winform下载文件并显示进度条
private void btnDown_Click(object sender, EventArgs e) { DownloadFile("http://localhost:1928/We ...
- 7.19 SQL——函数
select * from student select * from score select * from teacher select * from course select * from c ...