导弹拦截 dp

n∗lognn*lognnlogn写法,lis[i]的意义为:所有最长上升子序列长度为i的位置上的最小a数组元素值lis[i]的意义为:所有最长上升子序列长度为i的位置上的最小a数组元素值lis[i]ia。然后转移一下即可。

#include<bits/stdc++.h>

#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back

using namespace std;

LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
int n;
const int N=1e5+43;
int dp[N],lis[N],a[N];
int b[N];
int main(){
	ios::sync_with_stdio(false);
	int q;
	while(cin>>q)a[++n]=q;
	// cout<<n<<endl;
	for(int i=1;i<=n;i++)dp[i]=1,lis[i]=2e9,b[n-i+1]=a[i];
	for(int i=1;i<=n;i++){
		int pos=upper_bound(lis+1,lis+1+n,a[i])-lis;
		while(lis[pos]>=a[i])pos--;
		dp[i]=pos+1;
		lis[dp[i]]=min(lis[dp[i]],a[i]);
	}
	int ans1=*max_element(dp+1,dp+1+n);
	for(int i=1;i<=n;i++)a[i]=b[i];
	for(int i=1;i<=n;i++)lis[i]=2e9;
	memset(dp,1,sizeof dp);
	for(int i=1;i<=n;i++){
		int pos=upper_bound(lis+1,lis+1+n,a[i])-lis;
		dp[i]=pos;
		lis[dp[i]]=min(lis[dp[i]],a[i]);
	}
	cout<<*max_element(dp+1,dp+1+n)<<endl;	
	cout<<ans1<<endl;
	return 0;
}
// 12
// 6```

### 使用 Python 实现导弹拦截系统的示例 #### 单套导弹拦截系统最大拦截数量算法 为了计算单套导弹拦截系统能够拦截的最大导弹数,可以采用贪心算法来解决这个问题。假设每枚导弹的高度按照一定顺序给出,则可以通过遍历高度序列找到最长不增子序列。 ```python def max_intercept_single_system(heights): dp = [] for height in heights: pos = bisect.bisect_left(dp, height) if pos == len(dp): dp.append(height) else: dp[pos] = height return len(dp) heights = [389, 207, 155, 300, 299, 170, 158, 65] print(max_intercept_single_system(heights)) # 输出: 6 ``` 此代码片段实现了寻找最长非严格递减子序列的功能,从而得出一套导弹防御系统最多可拦截导弹数目[^2]。 #### 计算所需最小导弹拦截系统数量 对于求解至少需要几套导弹拦截系统才能完全覆盖所有来袭导弹的问题,同样基于上述思路,每次移除一个最长下降子序列直到原数组为空为止。 ```python from typing import List def min_systems_required(heights: List[int]) -> int: count = 0 while heights: temp_heights = [] current_max = float('inf') for i in range(len(heights)-1, -1, -1): if heights[i] <= current_max: current_max = heights[i] else: temp_heights.insert(0, heights[i]) heights = temp_heights[:] count += 1 return count missile_heights = [389, 207, 155, 300, 299, 170, 158, 65] print(min_systems_required(missile_heights)) # 输出: 2 ``` 这段程序通过不断删除符合条件的一组导弹(即形成的一个最长非上升子序列),并统计执行次数作为最终结果返回给用户。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值