最少拦截系统(各类题型总结)

1.

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2

这道题是典型的lis的升级版具体请看代码:

#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
long long a,b,c,d,sum[1010],maxn,r[1010];
int main(){
    while(scanf("%lld",&a)!=EOF&&a){
        memset(r,0,sizeof(r));
        memset(sum,0,sizeof(sum));//初始化数组
        for(int i=0;i<a;i++){
            scanf("%lld",&r[i]);
            sum[i]=1;//sum[i]代表的是最少的拦截系统
        }
        for(int i=1;i<a;i++){
            for(int j=0;j<i;j++){
                if(r[i]>r[j]&&sum[j]+1>sum[i]){
                    sum[i]=sum[j]+1;
                }
            }
        }
        maxn=-1;
        for(int i=0;i<a;i++){
            maxn=max(maxn,sum[i]);//求出sum的最大值才能把所有导弹拦截下来
        }
        printf("%lld\n",maxn);
    }
    return 0;
}

2.

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是 \le 50000≤50000 的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出格式
输入格式:
1 行,若干个整数(个数 <= 100000)
输出格式:
2 行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入样例:
389 207 155 300 299 170 158 65
输出样例:
6
2

分设两个函数,用动态规划来做:(详解请看代码)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll r[100010],dp[100010];
void dpa(ll i){//求最长下降子序列的函数
    r[0]=0x3f3f3f3f;//对r[0]初始化为无穷大
    ll maxn=-1;//maxn用来存最大值
    for(int j=1;j<=i;j++){
        dp[j]=0;
        for(int k=0;k<j;k++){
            if(r[k]>=r[j]){//注意等号,联系题意只要不上升就行
                dp[j]=max(dp[k]+1,dp[j]);
                if(dp[j]>maxn)
                    maxn=dp[j];
            }
        }
    }
    printf("%lld\n",maxn);
}
void fab(ll i){//用来求最少的导弹系统数目
    r[0]=-0x3f3f3f3f;//对r[0]初始化为负无穷
    ll minx=-1;
    for(ll j=1;j<=i;j++){
        for(ll k=0;k<j;k++){
            if(r[k]<r[j]){
                dp[j]=max(dp[j],dp[k]+1);
                //printf("%lld\n",dp[j]);
                if(minx<dp[j]){
                    minx=dp[j];//此时用dp存最少的导弹系统数目
                }
            }
        }
    }
    printf("%lld\n",minx);
}
int main(){
    ll t;
    ll i=1;//数据范围用long long 
    memset(dp,0,sizeof(dp));
    memset(r,0,sizeof(r));
    while(scanf("%lld",&t)!=EOF&&t){//注意输入格式是一个坑点
        r[i]=t;
        i++;
    }
    dpa(i-1);//求最大下降子序列的和
    memset(dp,0,sizeof(dp));//对dp所有数据初始化为0
    fab(i-1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liubang00001/article/details/81559405