导弹拦截

上个大周我居然忘写博客了这里写图片描述,据说再不写我就要爆炸了,所以赶紧来补一篇。
好吧我们第二次学动态规划,上次听过就忘得差不多了,隔了两天我终于把我上次欠下的题给A掉了。

导弹拦截

//怎么样是不是感觉很熟,没错,DP入门题之一。鉴于大家都知道,所以在此不附题目。

主要思路

首先,从题目中以后的每一发炮弹都不能高于前一发的高度我们不难看出,这题的第一问是最长不上升子序列。我们设一个f数组,用来表示拦截到第i发炮弹时已经拦截的炮弹数量,如果第j个导弹比第i个要低的话,就说明前面肯定没有拦截到第j个,于是我们就可以从第一个到第i-1个中进行枚举,选择在第j个之前的f中最大的数值,然后加上自身,则可得到到第j个元素时的最长不上升子序列,然后在f中从1到n进行枚举,就能得到整串数字的最长上升子序列,即第一问。

第二问老师讲的是贪心算法,即从第i个元素前的i-1个元素中,选择最接近但大于第i个元素的元素与其分为一组,以此类推,得到最少分组,再减去1即为第二问所求。但是我觉得代码实现有点……所以我听了同桌的意见,第二问其实可以看做最长上升子序列,与上一问类似,改变判断条件即可,如代码所示。

代码如下

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a[201],f[210]={},maxx1=0,maxx2=0,t[210]={};
    cin>>n;
    for(int i=1;i<=n;i++)
     cin>>a[i];
    f[1]=1;//我们需要从第二个元素开始比较,所以要先将f[1]定义为1
    for(int i=2;i<=n;i++)
    {
     for(int j=1;j<i;j++)
      if(a[j]>=a[i]&&f[j]>f[i]) f[i]=f[j];//将每一个元素与其前面的元素比较,并选择之前的最长上升子序列
     f[i]++;//累加自身
    }
    for(int i=1;i<=n;i++)//在n个f[i]中寻找最长上升子序列为本题答案
     if(f[i]>maxx1)
      maxx1=f[i];
    t[1]=1;//与上一问基本相同,求最长上升子序列
    for(int i=2;i<=n;i++)
     {
        for(int j=1;j<=i;j++)
         if(a[i]>a[j]&&t[i]<t[j]) t[i]=t[j];//将第一问中判断a[j]>=a[i]变为a[i]>a[j]
        t[i]++;
     }
    for(int i=1;i<=n;i++)
     if(t[i]>maxx2)
      maxx2=t[i];
    cout<<maxx1<<endl;
    cout<<maxx2<<endl;
    return 0;
}

注意

依旧是细节,本人因为没有给t[1]赋值,第一次只拿了60分~所以,细节决定成败啊~

### 使用 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、付费专栏及课程。

余额充值