1 条题解

  • 0
    @ 2026-2-3 10:10:39
    #include<bits/stdc++.h>
    using namespace std;
    
    // [1] 临时存储输入的单个导弹高度
    int n; 
    // [2] 存储所有导弹高度的序列
    vector<int> arr;
    
    int main() {
        // [3] 循环读取输入的导弹高度,直到输入结束
        while(cin>>n){
        	arr.push_back(n);  // 将当前导弹高度加入序列
        }
    
        // ========== 模块1:计算最多能拦截的导弹数(最长不递增子序列) ==========
        // [4] dp数组,dp[i]表示以第i枚导弹结尾的最长不递增子序列长度,初始值为1(每个导弹自身为一个子序列)
        vector<int> dp(arr.size(),1);
        
        // [5] 遍历每一枚导弹(从第2枚开始,索引从1开始)
        for(int i=1;i<arr.size();i++){
        	// [6] 遍历当前导弹之前的所有导弹,寻找可衔接的不递增序列
        	for(int j=i-1;j>=0;j--){
        	 	// [7] 如果当前导弹高度不大于之前的导弹高度,说明可以加入该序列
        	 	if(arr[i]<=arr[j]){
        	 		dp[i]=max(dp[i],dp[j]+1);  // 更新当前序列的最长长度
    			}
    		}
    	}
    	
    	// [8] 对dp数组排序,最后一个元素即为最长不递增子序列的长度(最多拦截数)
    	sort(dp.begin(),dp.end());
    	cout<<dp[arr.size()-1]<<endl;  // 输出最多能拦截的导弹数
    	
    	// ========== 模块2:计算拦截所有导弹最少需要的系统数 ==========
    	// [9] dp_two数组,每个元素是一个vector,存储对应系统拦截的导弹高度序列
    	vector<int> dp_two[1100];
    	// [10] 当前已启用的系统数量,初始为1(第一枚导弹需要第一个系统)
    	int sum=1;
    	// [11] 第一个系统先拦截第一枚导弹
    	dp_two[sum].push_back(arr[0]);
    	
    	// [12] 遍历剩下的所有导弹(从第2枚开始)
    	for(int i=1;i<arr.size();i++){
    		int flag=0;  // [13] 标记是否找到可拦截当前导弹的系统
        	// [14] 遍历所有已启用的系统,寻找可用系统
        	for(int j=1;j<=sum;j++){
        		int len=dp_two[j].size();  // [15] 获取当前系统最后一枚导弹的索引
        		// [16] 如果当前导弹高度不大于该系统最后一枚导弹的高度,说明可以加入该系统
        		if(arr[i]<=dp_two[j][len-1]){
        			flag=1;  // 标记找到可用系统
        			dp_two[j].push_back(arr[i]);  // 将当前导弹加入该系统的拦截序列
        			break;  // 找到后跳出循环,不再检查其他系统
    			}
    		}
    		// [17] 如果没有找到可用系统,新增一套系统
    		if(flag==0){
    			sum++;  // 系统数量加1
    			dp_two[sum].push_back(arr[i]);  // 新系统拦截当前导弹
    		}
    	}
    	// [18] 输出最少需要的系统数量
    	cout<<sum;
        return 0;                  
    }
    
    • 1

    信息

    ID
    133
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者