UESTC 2015dp专题 N 导弹拦截 dp
导弹拦截
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/contest/show/65
Description
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都要 高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹,同时,司令部想知道拦截下来的导弹 的高度。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。
Input
第一行是一个整数t,代表case数。 对于每一个case,第一行是一个整数n(1≤n≤100000); 第二行是n个非负整数,表示第n枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。数据保证高度不会超过100000.
Output
对于每一个case,第一行输出最多能拦截的导弹数,第二行按来袭顺序输出拦截下来的导弹的高度构成的序列,以一个空格隔开。若有不止一种方法可以拦截最多的导弹,输出字典序最小的。
Sample Input
1 5 1 6 3 5 7
Sample Output
4 1 3 5 7
HINT
题意
题解:
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <ctime> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200001 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; //const int inf=0x7fffffff; //нчоч╢С const int inf=0x3f3f3f3f; /* inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } */ inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } //************************************************************************************** int a[maxn]; int dp[maxn]; int ans[maxn]; vector<int> k; int main() { int t=read(); while(t--) { memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); memset(ans,0,sizeof(ans)); k.clear(); int n=read(); for(int i=1;i<=n;i++) { a[i]=read(); ans[i]=inf; } int max_ans=0; for(int i=1;i<=n;i++) { int d=lower_bound(ans+1,ans+1+n,a[i])-ans; ans[d]=a[i]; dp[i]=d; max_ans=max(max_ans,d); } printf("%d\n",max_ans); int kiss=inf; for(int i=n;i>=1;i--) { if(!max_ans) break; if(dp[i]==max_ans&&a[i]<kiss) { kiss=a[i]; k.push_back(a[i]); max_ans--; } } int first=1; for(int i=k.size()-1;i+1;i--) { if(first) { printf("%d",k[i]); first=0; } else printf(" %d",k[i]); } printf("\n"); } }