[转]拦截导弹类问题 (Codevs4888零件分组POJ1065Wooden Sticks)(LIS及其覆盖问题)

本文探讨了拦截导弹问题的算法解决方案,通过最长不上升子序列和非增子序列分组来求解,并引入Dilworth定理简化问题。同时介绍了零件分组问题的解决方法。

原文←

拦截导弹

题意:求最长不上升子序列长度;求一个序列最少分成几个非增子序。

第一问易求,已知序列a,令f[i]为a前i个元素的最长非增子序的长度,则有
f[i]=max{f[i],f[j]+1} (1<=j<=i-1且h[j]>=h[i]).
LIS另有nlogn做法,设g[i]为长度为i的最长不上升结尾最小是什么,二分查找更新次数组可得长度。解本题则可以倒序做LIS。
对于第二问,可以维护一个单调序列,为现有导弹拦截系统的最大高度,顺序处理序列,每次贪心的使用大于该导弹高度最小的来拦截这个导弹,显然这样比使用一个可以拦截更高的系统更优。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; 

const int INF=0x3f3f3f3f;
int a[30],f[30],g[30],n;

int main()
{
    while(~scanf("%d",&a[++n]));
    --n;
    memset(f,63,sizeof f);
    for(int i=n;i>0;--i)//倒序LIS 
    {
        int p=lower_bound(f+1,f+n+1,a[i])-f;
        f[p]=a[i];
    }
    printf("%d\n",lower_bound(f+1,f+n+1,INF)-f-1);
    memset(g,63,sizeof g);//初始时可以拦截任意高度的导弹 
    for(int i=1;i<=n;++i)
    {
        int p=lower_bound(g+1,g+n+1,a[i])-g;
        g[p]=a[i];
    }
    printf("%d\n",lower_bound(g+1,g+n+1,INF)-g-1);//找到最后一个使用过的
    return 0;
}

不难发现,第二问按照贪心的思路打出的实际上是一个nlogn的LIS。这涉及到一个定理。

Dilworth定理:对于一个偏序集,最少链划分等于最长反链长度.

也就是说把一个数列划分成最少的最长不上升子序列的数目就等于这个数列的最长不下降子序列的长度。

零件分组 Wooden Sticks

现有一些棍状零件,每个零件都有一定的长度(Li)和重量(Wi)。现在为了加工需要,要将他们分成若干组,使每一组中的零件都能排成一个长度和重量都不下降(若i < j,则Li<=Lj,Wi<=Wj,其中i,j为在同一组中的序号)的序列。请问至少要分成几组?

先按照长度(或重量)双关键字排序,则答案序列一定是该序列的子序。则问题转化为原问题二,问未排序的那一个元素序列最少分成多少最长的非降的子序列。求这个序列的最长非增子序即可。
nlogn的非增序列处理比较复杂,(因为处理到a[i]是,要找到小于该值的最大元素,如果其最小则左移,需要从n到1处理)。可以同第一问一样转化为从右向左做LIS,也可以全部取负数做LIS(废话)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN=100000+5,INF=0x3f3f3f3f;
struct elem
{
    int l,w;
    bool operator < (const elem& b)const
    {
        if(l==b.l)
            return w<b.w;
        return l<b.l;
    }
}e[MAXN];
int n,m;
int f[MAXN];

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&e[i].l,&e[i].w);
    sort(e+1,e+n+1);
    memset(f,63,sizeof f);
    for(int i=1;i<=n;++i)
    {
        int p=lower_bound(f+1,f+n+1,-e[i].w)-f;
        f[p]=-e[i].w;
    }
    printf("%d",lower_bound(f+1,f+n+1,INF)-f-1);
    return 0;
}
内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值