CodeFoces 500E - New Year Domino

本文介绍了一种离线算法来解决特定情况下牌子摆放的问题。通过预处理和分类讨论,实现了从右到左枚举并更新状态的过程,最终得到了最小花费的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先将所有的牌子放倒,那么花费就是牌子L和牌子R之间的空隙长度。

有一种特殊情况,存在牌子P(p < L)特别长,以至于影响了L,R之间的空隙长度。

所以我只想到了一种离线算法。

cov[i] 记录覆盖牌子i的编号。

dis[i] 记录推到牌子i所能到达的最远距离。

cost[i]记录L= i,R = n 时的最小花费。

首先预处理出dis[i],cost[i]。

然后将询问按L排序,然后从右到左枚举牌子。

枚举时不断更新cov[i],然后分类讨论得到答案。

弱用了三棵线段树才水过去,应该存在更简洁的方法。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>
#include <iomanip>

#pragma comment(linker,"/STACK:1024000000");
#define EPS (1e-6)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define mod 1000000007

/** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x)
{
    char c;
    while(!d);
    x=c-'0';
    while(d)p;
    return x;
}
template<class T> inline T& RDD(T &x)
{
    char c;
    while(g,c!='-'&&!isdigit(c));
    if (c=='-')
    {
        x='0'-g;
        while(d)n;
    }
    else
    {
        x=c-'0';
        while(d)p;
    }
    return x;
}
inline double& RF(double &x)      //scanf("%lf", &x);
{
    char c;
    while(g,c!='-'&&c!='.'&&!isdigit(c));
    if(c=='-')if(g=='.')
        {
            x=0;
            double l=1;
            while(d)nn;
            x*=l;
        }
        else
        {
            x='0'-c;
            while(d)n;
            if(c=='.')
            {
                double l=1;
                while(d)nn;
                x*=l;
            }
        }
    else if(c=='.')
    {
        x=0;
        double l=1;
        while(d)pp;
        x*=l;
    }
    else
    {
        x=c-'0';
        while(d)p;
        if(c=='.')
        {
            double l=1;
            while(d)pp;
            x*=l;
        }
    }
    return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
using namespace std;

struct N
{
    int l,p;
}st[200010];

int far[200010];

int Max[800100];

int dis[200010];

int Val[800100];

LL cost[200100];

int Init(int site,int l,int r)
{
    if(l == r)
        return Val[site] = st[l].l+st[l].p;

    int mid = (l+r)>>1;

    return Val[site] = max(Init(site<<1,l,mid),Init(site<<1|1,mid+1,r));
}

void Update(int site,int l,int r,int x,int d)
{
    if(l == r)
    {
        Max[site] = max(Max[site],d);
        return ;
    }

    int mid = (l+r)>>1;

    if(x <= mid)
        Update(site<<1,l,mid,x,d);
    else
        Update(site<<1|1,mid+1,r,x,d);
    Max[site] = max(Max[site<<1],Max[site<<1|1]);
}

int Query(int site,int L,int R,int l,int r)
{
    if(L == l && R == r)
        return Max[site];

    int mid = (L+R)>>1;

    if(r <= mid)
        return Query(site<<1,L,mid,l,r);
    if(mid < l)
        return Query(site<<1|1,mid+1,R,l,r);

    return max(Query(site<<1,L,mid,l,mid),Query(site<<1|1,mid+1,R,mid+1,r));
}

int Query1(int site,int L,int R,int l,int r)
{
    if(L == l && R == r)
        return Val[site];

    int mid = (L+R)>>1;

    if(r <= mid)
        return Query1(site<<1,L,mid,l,r);
    if(mid < l)
        return Query1(site<<1|1,mid+1,R,l,r);

    return max(Query1(site<<1,L,mid,l,mid),Query1(site<<1|1,mid+1,R,mid+1,r));
}

int BS(LL x,int s,int e)
{
    int mid , site = 0;

    while(s <= e)
    {
        mid = (s+e)>>1;

        if(st[mid].p <= x)
            s = mid+1,site = mid;
        else
            e = mid-1;
    }

    return site;
}

void Cal(int x,int n)
{
    int site = BS(st[x].l+st[x].p,x,n);

    if(site == x)
        far[x] = x;
    else if(site == n)
        far[x] = n;
    else
        far[x] = Query(1,1,n,x,site);

    Update(1,1,n,x,far[x]);
}

int FindSite(int x,int l,int r)
{
    int mid,site = r;

    while(l <= r)
    {
        mid = (l+r)>>1;
        if(far[mid] == x)
            site = min(site,mid);
        if(far[mid] < x)
            l = mid+1;
        else
            r = mid-1;
    }
    return site;
}

struct Qu
{
    int l,r,site;
    LL anw;
}qu[200010];


bool cmp1(Qu q1,Qu q2)
{
    return q1.l < q2.l;
}

bool cmp2(Qu q1,Qu q2)
{
    return q1.site < q2.site;
}

struct Co
{
    int id;
    bool mark;
}cov[800100];

void InitCo(int site,int l,int r)
{
    if(l == r)
    {
        cov[site].id = l,cov[site].mark = true;
        return ;
    }
    int mid =(l+r)>>1;

    InitCo(site<<1,l,mid);
    InitCo(site<<1|1,mid+1,r);

    if(cov[site<<1].id == cov[site<<1|1].id && cov[site<<1].id != -1)
        cov[site].mark = true,cov[site].id = cov[site<<1].id;
    else
        cov[site].mark = false,cov[site].id = -1;
}

void UpdateCo(int site,int L,int R,int l,int r,int id)
{
    if(L == l && R == r)
    {
        cov[site].mark = true;
        cov[site].id = id;
        return ;
    }

    int mid = (L+R)>>1;

    if(cov[site].mark == true)
    {
        cov[site<<1] = cov[site];
        cov[site<<1|1] = cov[site];

        cov[site].mark = false;
        cov[site].id = -1;
    }

    if(r <= mid)
        UpdateCo(site<<1,L,mid,l,r,id);
    else if(mid < l)
        UpdateCo(site<<1|1,mid+1,R,l,r,id);
    else
    {
        UpdateCo(site<<1,L,mid,l,mid,id);
        UpdateCo(site<<1|1,mid+1,R,mid+1,r,id);
    }

    if(cov[site<<1].id == cov[site<<1|1].id && cov[site<<1].id != -1)
        cov[site].mark = true,cov[site].id = cov[site<<1].id;
    else
        cov[site].mark = false,cov[site].id = -1;
}

int QueryCo(int site,int L,int R,int x)
{
    if(cov[site].mark )
        return cov[site].id;

    int mid = (L+R)>>1;

    if(x <= mid)
        return QueryCo(site<<1,L,mid,x);
    else
        return QueryCo(site<<1|1,mid+1,R,x);
}

int main()
{
    int n,i,j,q;

    scanf("%d",&n);

    for(i = 1;i <= n; ++i)
        scanf("%d %d",&st[i].p,&st[i].l);

    memset(Max,0,sizeof(Max));

    Update(1,1,n,n,n);

    for(far[n] = n,i = n-1; i >= 1; --i)
        Cal(i,n);

    Init(1,1,n);

    for(i = 1;i <= n; ++i)
        dis[i] = Query1(1,1,n,i,far[i]);

    for(cost[n] = 0,i = n-1;i >= 1; --i)
    {
        if(far[i] == n)
            cost[i] = 0;
        else
            cost[i] = cost[far[i]+1] + st[far[i]+1].p - dis[i];
    }

    scanf("%d",&q);

    int site;

    for(i = 1;i <= q; ++i)
    {
        scanf("%d %d",&qu[i].l,&qu[i].r);
        qu[i].site = i;
    }

    sort(qu+1,qu+q+1,cmp1);

    InitCo(1,1,n);

    for(j = q,i = n;i >= 1; --i)
    {
        UpdateCo(1,1,n,i,far[i],i);
     
        while(j >= 1 && qu[j].l == i)
        {
            if(far[i] >= qu[j].r)
                qu[j].anw = 0;
            else
            {
                site = QueryCo(1,1,n,qu[j].r);
                if(far[i] >= site)
                    qu[j].anw = 0;
                else
                    qu[j].anw = cost[i] - cost[site];
            }
            j--;
        }
    }

    sort(qu+1,qu+q+1,cmp2);

    for(i = 1;i <= q; ++i)
    {
        printf("%I64d\n",qu[i].anw);
    }


    return 0;
}

内容概要:本文档详细介绍了基于MATLAB实现多目标差分进化(MODE)算法进行无人机三维路径规划的项目实例。项目旨在提升无人机在复杂三维环境中路径规划的精度、实时性、多目标协调处理能力、障碍物避让能力和路径平滑性。通过引入多目标差分进化算法,项目解决了传统路径规划算法在动态环境和多目标优化中的不足,实现了路径长度、飞行安全距离、能耗等多个目标的协调优化。文档涵盖了环境建模、路径编码、多目标优化策略、障碍物检测与避让、路径平滑处理等关键技术模块,并提供了部分MATLAB代码示例。 适合人群:具备一定编程基础,对无人机路径规划和多目标优化算法感兴趣的科研人员、工程师和研究生。 使用场景及目标:①适用于无人机在军事侦察、环境监测、灾害救援、物流运输、城市管理等领域的三维路径规划;②通过多目标差分进化算法,优化路径长度、飞行安全距离、能耗等多目标,提升无人机任务执行效率和安全性;③解决动态环境变化、实时路径调整和复杂障碍物避让等问题。 其他说明:项目采用模块化设计,便于集成不同的优化目标和动态环境因素,支持后续算法升级与功能扩展。通过系统实现和仿真实验验证,项目不仅提升了理论研究的实用价值,还为无人机智能自主飞行提供了技术基础。文档提供了详细的代码示例,有助于读者深入理解和实践该项目。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值