【基础】导弹拦截

一、描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹的枚数和导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,每个数据之间至少有一个空格),计算这套系统最多能拦截多少导弹。

二、输入描述

第1行有1个整数n,代表导弹的数量。(n<=1000)

第2行有n个整数,代表导弹的高度。(雷达给出的高度数据是不大于30000的正整数)

三、输出描述

输出这套系统最多能拦截多少导弹。

四、AC代码(详解见下文)
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int dh[n+10]; 
	int dp[n+10];
	for(int i=0;i<n;i++)
	{
		cin>>dh[i];
		dp[i]=1;
	}
    int maxx=0;
	for(int i=1;i<n;i++)
	{
		for(int j=0;j<i;j++)
		{
			if(dh[j]>dh[i]) dp[i]=max(dp[i],dp[j]+1);
		}
		maxx=max(maxx,dp[i]);
	}
	cout<<maxx<<endl;
	return 0;
}
五、详解

1.将题目要求我们要做的事抽象来看就是:寻找最长递减子序列。通俗点就是:在个数组中,找到最长的且递减的按输入顺序(可以跳过数字)的一列数。

2.知道了我们要干的事就可以很容易想到用动态规划来解决。

3.接下来就是找到转换方程式了,即dp[i]=max(dp[i],dp[j]+1)

4.代码详解

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;//n即为导弹数量
	cin>>n;//输入导弹数量
	int dh[n+10];//dh为导弹的高度
	int dp[n+10];//dp为可拦截的导弹数量
	for(int i=0;i<n;i++)//从0到n-1
	{
		cin>>dh[i];//输入每个导弹的高度
		dp[i]=1;//将每个dp的初始值赋值为1,因为至少可拦截当下导弹
	}
    int maxx=0;//设一个可拦截导弹数最大值,初始值为0
	for(int i=1;i<n;i++)//从1到n-1因为第0个dp长度只能为1即只能拦截第0个导弹
	{
		for(int j=0;j<i;j++)//从0到i-1因为dp是向前看且不能向当下和后面看
		{
			if(dh[j]>dh[i])//如果i前面有j导弹的高度比i的高度高
            {
                dp[i]=max(dp[i],dp[j]+1);//那么dp[i]就为dp[j]+1(因为是j最长加上当前导弹)和它的最大值
            }
		}
		maxx=max(maxx,dp[i]);//比较最大值
	}
	cout<<maxx<<endl;//输出最大值
	return 0;
}
六、另一种方式
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
vector<int> nums;
int nums_size;
int max_tot=0;
int dfs(int first,int tot)
{	if(first==nums_size-1)
	{
		max_tot=max(tot,max_tot);
		return max_tot;
	}
	for(int i=first+1;i<nums_size;i++)
	{
		if(nums[i]<nums[first])
		{
			tot++;
			dfs(i,tot);
			tot--;
		}
	}
	max_tot=max(tot,max_tot);
	return max_tot;
}
int main()
{
	int n;
	cin>>n;
	int x;
	while(cin>>x)
	{
		nums.push_back(x);
		if(cin.get()=='\n') break;	
	} 
	nums_size=nums.size();
	int max_cd=0;
	for(int i=0;i<nums_size;i++)
	{
		max_cd=max(max_cd,dfs(i,1));
	}
	cout<<max_cd;
	return 0; 
}
相关推荐
j_xxx404_43 分钟前
C++算法入门:二分查找合集(二分查找|在排序数组中查找元素的第一个和最后一个位置)
开发语言·c++
lizz311 小时前
C++操作符重载深度解析
java·c++·算法
十五年专注C++开发1 小时前
QTableWidget和QTableView插入数据比较
c++·qt·qtablewidget·qtableview
无限进步_1 小时前
【C语言】队列(Queue)数据结构的实现与分析
c语言·开发语言·数据结构·c++·算法·链表·visual studio
特立独行的猫a1 小时前
Google C++ 编码规范核心要点总结 (2025精简版)
开发语言·c++·编码规范
李余博睿(新疆)1 小时前
c++经典练习题-分支练习(2)
c++·算法
superman超哥1 小时前
仓颉语言中网络套接字封装的深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
暗然而日章2 小时前
C++基础:Stanford CS106L学习笔记 11 Lambdas表达式
c++·笔记·学习
辞旧 lekkk2 小时前
【c++】c++11(上)
开发语言·c++·学习·萌新
彭世瑜2 小时前
C/C++:libfort用于在终端输出表格
c语言·开发语言·c++