HDOJ 1257

最少拦截系统

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13135    Accepted Submission(s): 5235


Problem Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
 

Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
 

Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
 

Sample Input
   
   
   
   
8 389 207 155 300 299 170 158 65
 

Sample Output
   
   
   
   
2
 

Source
浙江工业大学第四届大学生程序设计竞赛
 

Recommend
JGShining
 
两种方法,一种是直接去裸地DP,O(n^2), 还有一种二分贪心的优化,O(n * log(n));
第一种 30MS
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <iomanip>

using namespace std;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
#define clr(a,b) memset(a,b,sizeof(a))
#define lson l , mid  , rt << 1
#define rson mid + 1 , r , rt << 1|1
#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)
#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)
#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)
#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)
#define mid ((l + r) >> 1)
#define mk make_pair
const int MAXN = 30000 + 10;
const int maxw = 100 + 20;
const int MAXNNODE = 10000 +10;
const long long LLMAX = 0x7fffffffffffffffLL;
const long long LLMIN = 0x8000000000000000LL;
const int INF = 0x7fffffff;
const int IMIN = 0x80000000;
#define eps 1e-8
#define mod 10007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
typedef pair<int , int> pii;
const D e = 2.718281828459;
int a[MAXN] , dp[MAXN];
int main()
{
    //ios::sync_with_stdio(false);
#ifdef Online_Judge
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif // Online_Judge
    int n;
    while(~scanf("%d" , &n))
    {
        clr(dp , 0);
        int maxn = 0;

        FORR(i , 1 , n)
        {
            scanf("%d" , &a[i]);
            int tmp = 0;
            FOR(j , 1 , i)
            {
                if(a[j] < a[i] && tmp < dp[j])tmp = dp[j];
            }
                dp[i] = tmp + 1;
                maxn = max(maxn , dp[i]);
        }
        printf("%d\n" , maxn);
    }
    return 0;
}
第二种 0MS
#include<stdio.h>
int main ()
{
     int a[30005],aa[30005];
     int l,i,j,mid,low,up,n;
     while(~scanf("%d",&n))
     {
        for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
        aa[1]=a[1];
        l=1;
        for(i=2;i<=n;i++)
        {
           up=l;
           low=1;
           while(low<=up)
           {
  	     mid=(up+low)/2;
  	     if(aa[mid]>a[i])
  	     up=mid-1;
  	     else
  	     low=mid+1;
            }
            if(low>l)
            l++;
            aa[low]=a[i];
         }
         printf("%d\n",l);
     }
     return 0;
}




你可能感兴趣的:(dp,ACM,贪心)