1 /*
 2     导弹拦截问题(也称为最长不上升子序列问题)是动态规划中的经典问题之一。问题的描述如下:
 3     给定一个导弹飞行高度的序列,要求拦截所有导弹。拦截系统有一个限制:每次拦截的导弹高度不
 4     能高于前一次拦截的导弹高度。问最少需要多少套拦截系统才能拦截所有导弹,或者一套拦截系统最多能拦截多少导弹。
 5     这个问题可以转化为两个子问题:
 6 
 7     1. 最少需要多少套拦截系统:即求导弹高度序列的最长上升子序列(LIS)的长度。
 8     2. 一套拦截系统最多能拦截多少导弹:即求导弹高度序列的最长不上升子序列(LNIS)的长度。
 9     
10     示例数据:{189, 207, 155, 200, 99}
11     
12 */
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;


int maxMissiles(vector<int>& heights){
    int n = heights.size();
    vector<int> dp(n,1);//dp[i]是当前高度最大不上升子序列的长度
    for(int i=1;i<n;i++){
        for(int j=0;j<i;j++){
            if(heights[j]>=heights[i]){
                dp[i]=max(dp[j]+1,dp[i]);
            }
        }
    }//到这里,dp就已经得到了所有以当前高度值结尾的最大不上升子序列的值
    return *max_element(dp.begin(),dp.end());
}
int maxSystem(vector<int>& heights){
    int n = heights.size();
    vector<int> dp(n,1);
    for(int i = 1;i < n;i++){
        for(int j = 0;j < i;j++){
            if(heights[j]<=heights[i]){
                dp[i]=max(dp[j]+1,dp[i]);
            }
        }
    }
    
    return *max_element(dp.begin(),dp.end());
}
int main(void){
    vector<int> heights={189,207,155,200,99,50};
    int n = maxMissiles(heights);
    int m = maxSystem(heights);
    printf("最大拦截导弹的个数为:%d\n需要的系统个数:%d",n,m);
    return 0;
}

 

posted on 2025-03-30 16:01  FYJUN2077  阅读(17)  评论(0)    收藏  举报