hdu 1257 最少拦截系统 (数组)

小记:因为当前的导弹能打的高度不能高于前一个导弹的高度。所以从第一炮开始,如果能打就打,不能打就再加个系统,对系统编号。以后的要拦截的高度,从第一个系统开始,若它能打,就打,更新它的可打高度,然后退出去,再看下一个拦截高度。若是不能打, 就换下一个看,若都不可以,则只能增加一个新系统了。 就这样.


代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

const int MAX_ = 30005;

int p[MAX_];
int d[MAX_];

int main() {
    int n,k;
    while(cin>>n){
        k = 0;d[0] = 0;
        for(int i = 0; i < n; ++i){
            cin>>p[i];
            for(int j = 0; j <= k; ++j){
                if(d[j] > p[i]){
                    d[j] = p[i];
                    break;
                }
                else if(j == k){
                    k++;
                    d[k] = p[i];
                    break;
                }
            }
        }
        cout<<k<<endl;
    }
    return 0;
}

另一种解法就是最长上升子序列。因为每个导弹都必须拦截,而且只能越拦越低,那么就相当于是求最长上升子序列的个数了。

而如果要求一个这样的系统最多能拦截多少个,那么就是求最长非降子序列. (两问加起来)是NOIP1999(提高组)第一题 


最长上升子序列解法:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 30010;
const int N = 100010;
const int INF = 0x7fffffff;

int a[MAX_];
int d[MAX_];

int main(){
	int n;
	while(~scanf("%d", &n)){
        REP(i,0,n){
            scanf("%d",&a[i]);
            d[i] = 1;
        }

        int ans = -INF;
        REP(i,1,n){
            REP(j, 0, i){
                if(a[j] < a[i]){
                    d[i] = max(d[j] + 1, d[i]);
                }
            }
            ans = max(ans, d[i]);
        }
        printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(hdu 1257 最少拦截系统 (数组))