导弹拦截

上个大周我居然忘写博客了这里写图片描述,据说再不写我就要爆炸了,所以赶紧来补一篇。
好吧我们第二次学动态规划,上次听过就忘得差不多了,隔了两天我终于把我上次欠下的题给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分~所以,细节决定成败啊~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值