UESTC 2015dp专题 N 导弹拦截 dp

导弹拦截

Time Limit: 20 Sec  Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/contest/show/65

Description

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都要 高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹,同时,司令部想知道拦截下来的导弹 的高度。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。
wij 千 克的蛋糕,Gorwin从左上角(1,1)的格子开始走,走到右下角(n,m)的格子。在每一步中,Gorwin可以向右或者向下走,即是:Gorwin 站在(i,j)的时候,她可以走向(i+1,j)或者(i,j+1) (然而她不能走出这个花园)。 当Gorwin到达一个格子的时候,她可以把那个格子里面的蛋糕吃完或者不吃。但是,她不能只吃一部分。她的胃不是那么大,所以她最多只能吃K千克的蛋 糕。现在,Gorwin站在左上角,她在看蛋糕园的地图,想要找出一条路,能够使得她吃到的蛋糕最多的一条路。请你来帮帮忙。

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");
    }
}

 

posted @ 2015-05-23 23:06  qscqesze  阅读(466)  评论(0编辑  收藏  举报