【CodeForces】704 B. Ant Man「建议收藏」

【CodeForces】704 B. Ant Man

大家好,又见面了,我是全栈君。

【题目】B. Ant Man

【题意】给定n个人的xi,ai,bi,ci,di,起点为s,终点为e,移动:

In simpler words, jumping from i-th chair to j-th chair takes exactly:

  • |xi - xj| + ci + bj seconds if j < i.
  • |xi - xj| + di + aj seconds otherwise (j > i).

求中间经过所有点恰好一次的最小代价。

【算法】动态规划

【题解】很巧妙的DP状态设计。(这样类似哈密顿路径的问题不能从图论方面考虑,否则很容易变成NP问题)

将代价拆分到每个点:

向左,起c+x,落b-x

向右,起d-x,落a+x

那么对于前i个点,有效信息只有这i个点中缺少多少入边和缺少多少出边。先无视s(起点)和t(终点),那么缺入边数和缺出边数相等。

令f[i][j]表示前i个点中缺少j条入/出边的最小代价,缺少入边的本质是被往左,缺少出边的本质是往右。

对于f[i-1][j],有以下四种转移:

被往右+往右:j>0,f[i][j]=f[i-1][j]+a[i]+d[i](两个x[i]抵消)——减少一条出边,同时增加一条出边

往左+被往左:j>0,f[i][j]=f[i-1][j]+b[i]+c[i]——减少一条入边,同时增加一条入边

被往右+往左:j>0,f[i][j-1]=f[i-1][j]+a[i]+c[i]+2*x[i]——减少一条入边和一条出边

往右+被往左:f[i][j+1]=f[i-1][j]+b[i]+d[i]-2*x[i]——增加一条入边和一条出边

最终答案为f[n][0]。

接下来解决s和t的问题,实际上s和t才能代表一个完整的点,所以将s当成一个完整的点,不把t看作一个点。

先经过s:会多一条不该有的入边,所以只要避免第二个和第三个转移。

先经过t:会少一条该有的入边,所以只要在j=0时强制进行第二个转移。

最后在到达n之前和st均有或均无时,不能成环,强制f[i][0]=inf。

复杂度O(n^2)。

【CodeForces】704 B. Ant Man「建议收藏」
【CodeForces】704 B. Ant Man「建议收藏」

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll inf=1e16,maxn=5010;
ll f[maxn][maxn];
int n,s,t,x[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
void m(ll &a,ll b){
    
    if(a>b)a=b;}
ll solve(){
    memset(f,0x3f,sizeof(f));
    int tot=0;f[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=i;j++)if(f[i-1][j]<inf){
            int S=j,T=S+tot;
            if(i==s){
                if(T)m(f[i][j],f[i-1][j]+c[i]+x[i]);
                m(f[i][j+1],f[i-1][j]+d[i]-x[i]);
            }
            else if(i==t){
                if(S)m(f[i][j-1],f[i-1][j]+a[i]+x[i]);
                m(f[i][j],f[i-1][j]+b[i]-x[i]);
            }
            else{
                if(S)m(f[i][j],f[i-1][j]+a[i]+d[i]);
                if(T)m(f[i][j],f[i-1][j]+b[i]+c[i]);
                if(S&&T)m(f[i][j-1],f[i-1][j]+a[i]+c[i]+2*x[i]);
                m(f[i][j+1],f[i-1][j]+b[i]+d[i]-2*x[i]);
            }
        }
        if(i==s)tot--;if(i==t)tot++;
        if(i!=n&&tot==0)f[i][0]=inf;
    }
    return f[n][0];
}
int main(){
    scanf("%d%d%d",&n,&s,&t);
    for(int i=1;i<=n;i++)scanf("%d",&x[i]);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    printf("%lld",solve());
    return 0;
}

View Code

 

PS:我在这场比赛进行Virtual participation的时候,大力贪心出B……然后排名好高啊><。

至今无人能证明但AC了的贪心(似乎有人给反例):初始s-t,然后考虑一个一个点找最优位置插入。

转载于:https://www.cnblogs.com/onioncyc/p/8277875.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107759.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • webstrom 2022激活码_在线激活

    (webstrom 2022激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

  • datagrip激活码_最新在线免费激活[通俗易懂]

    (datagrip激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • 你尚未连接代理服务器可能有问题或地址不正确(如何查看代理服务器ip)

    在进行一下操作室不需保证你的网线是接通的(你的右下角应该显示的是,而不是)当你的电脑显示:“无法连接到安全检查代理服务器,本地IP地址非法”,解决办法分一下几步:第一步:先检查你的ARP防火墙配置的是否正确,如果正确,进行下一步;第二部:检查你的IP地址和默认网关是否正确,无误后,进行下一步;第三部:检查你的无线网卡是否禁用了,如果禁用了,进行下一步;第四部:在DOS命令中输入

  • 别了,等待

    别了,等待别了,等待

  • 你还不知道Java异或运算符的妙用?

    你还不知道Java异或运算符的妙用?异或(XOR)运算符当两个boolean类型的变量,locked^deleted,如果locked与deleted是不同的,返回true。如果两个操作数是相同的,则返回false。因此,当我们需要同时检查两个不成立的条件时,可以使用异或运算符号。假设我们有两个条件,A和B,下面显示了A^B的可能值:A^B操作等于(A&&!B)||(!A&&B)。在Java中使用接下来让我看一下Java中的异或操作,当然我们可以.

  • 异步fifo的工作原理(netty异步方法)

    FPGA(一):异步FIFO实现(包含源码和仿真文件)一、异步FIFO的重要参数及其作用1、FIFO:FirstInputFirstOutput,即先入先出队列,本质是RAM。FIFO有几个最重要的参数:2、wr_clk:写时钟,所有与写有关的操作都是基于写时钟;3、rd_clk:读时钟,所有与读有关的操作都是基于读时钟;4、FIFO_WIDTH:FIFO的位宽,即FIFO中每个地址对应的数据的位宽;5、FIFO_DEPTH:FIFO的深度,即FIFO中能存入多少个(位宽为FIFO_

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号