(序列)(贪心)(LIS)(区间dp)最少拦截系统

3 篇文章 0 订阅
文章介绍了如何使用贪心算法解决一个导弹拦截问题,通过扫描数组找到未出现过的最大值作为起点,然后标记并更新最大值,证明了贪心策略的最优性。作者提到了在实现过程中需要注意的细节,如初始化和循环条件,并提供了C++代码示例。
摘要由CSDN通过智能技术生成

2023年4月2日

https://vjudge.csgrandeur.cn/contest/550913#problem/G

注意到网上没有什么贪心做法的证明,就发一篇出来
我的思路
没看出来是个dp,就想想贪心。
扫描数组,找到第一个没出现过的,设为最大值,cnt++,以其为起点,再一重循环往下扫描,比最
大值小的就标记,然后更新最大值,
n方复杂度,和dp差不多
卡壳点
一个是多组输入没有初始化,再就是在第二重的j指针扫描里,伪代码的描述有缺漏,应该要扫到比最大值小且没标记过的才标记并更新最大值,伪代码写的不够完备,**主要原因应该是下意识的省略了很多步骤,即跳步,写流程时贪快了**
贪心证明
主要要证明的就是拦截系统拦截第一个导弹能得到最优方案的问题

不需要考虑哪个拦截系统系统的高度亏损,高的拦截中的,中的拦截小的 ,和高的拦截小的,中的拦截中的最终结果都是得到一个中一个小的拦截系统,位置也是相同的,所以两种方案等价,

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e3 + 10;
int a[N];
bool st[N];
int main(){
    int n;
    while(~scanf("%d",&n)){
        int cnt = 0;
        for(int i = 1;i <= n;i++){
            cin >> a[i];   
        }
        memset(st,0,sizeof st);
        for(int i = 1;i <= n;i++){
            int maxn ;
            if(!st[i]){
                maxn = a[i];
                cnt++;
                for(int j = i+1;j <= n;j++){
                    if(maxn >= a[j] && !st[j]) {st[j] = true,maxn = a[j];
                        // cout << a[j]<< endl;/
                    }
                    
                }
            }
            
        }
        cout << cnt << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值