题目


分析(dp)

考虑到对于一个排列单独抽出 \(1\sim i\) 可能会分成若干段,而贡献一定是固定的,不会影响之后的选择。

首先 \(a,c\) 加上 \(x\),\(b,d\) 减去 \(x\),那么贡献就转换为

\(\begin{cases}i<j,d_i+a_j\\i>j,c_i+b_j\end{cases}\)

同样考虑从小到大插入每一个数,

设 \(dp[i][j]\) 表示前 \(i\) 个数分成 \(j\) 段的最小权值。

若 \(i=St\),那么可以新开一段或者补到开头位置。

\(dp[i][j]=\min\{dp[i-1][j-1]+d_i,dp[i-1][j]+c_i(j>0)\}\)

若 \(i=Ed\),同理 \(dp[i][j]=\min\{dp[i-1][j-1]+b_i,dp[i-1][j]+a_i(j>0)\}\)

如果 \(i\) 不为开头或结尾,那么可以新开一段,合并两段,或者接在一段的开头或者结尾(但是不能替代 \(St\) 和 \(Ed\))

新开一段就是 \(dp[i][j]=\min\{dp[i-1][j-1]+b_i+d_i\}\)

合并两段就是 \(dp[i][j]=\min\{dp[i-1][j+1]+a_i+c_i\}\)

接到开头就是 \(dp[i][j]=\min\{dp[i-1][j]+b_i+c_i\}(j>(i>St))\)

接到末尾就是 \(dp[i][j]=\min\{dp[i-1][j]+a_i+d_i\}(j>(i>Ed))\)

最后答案就是 \(dp[n][1]\)


代码

#include <cstdio>
#include <cctype>
#include <cstring>
using namespace std;
const int N=5011; typedef long long lll;
int n,st,ed,x[N],a[4][N]; lll dp[2][N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void Min(lll &x,lll y){x=x<y?x:y;}
int main(){
n=iut(),st=iut(),ed=iut();
for (int i=1;i<=n;++i) x[i]=iut();
for (int i=1;i<=n;++i) a[0][i]=iut()+x[i];
for (int i=1;i<=n;++i) a[1][i]=iut()-x[i];
for (int i=1;i<=n;++i) a[2][i]=iut()+x[i];
for (int i=1;i<=n;++i) a[3][i]=iut()-x[i];
memset(dp[0],0x3f,sizeof(dp[0])),dp[0][0]=0;
for (int i=1;i<=n;++i){
memset(dp[i&1],0x3f,sizeof(dp[i&1]));
if (i==st){
for (int j=(i>ed);j<i;++j){
if (j) Min(dp[i&1][j],dp[(i&1)^1][j]+a[2][i]);
Min(dp[i&1][j+1],dp[(i&1)^1][j]+a[3][i]);
}
}else if (i==ed){
for (int j=(i>st);j<i;++j){
if (j) Min(dp[i&1][j],dp[(i&1)^1][j]+a[0][i]);
Min(dp[i&1][j+1],dp[(i&1)^1][j]+a[1][i]);
}
}else{
for (int j=(i>st)+(i>ed);j<i;++j){
if (j>1) Min(dp[i&1][j-1],dp[(i&1)^1][j]+a[0][i]+a[2][i]);
Min(dp[i&1][j+1],dp[(i&1)^1][j]+a[1][i]+a[3][i]);
if (j>(i>st)) Min(dp[i&1][j],dp[(i&1)^1][j]+a[2][i]+a[1][i]);
if (j>(i>ed)) Min(dp[i&1][j],dp[(i&1)^1][j]+a[0][i]+a[3][i]);
}
}
}
return !printf("%lld",dp[n&1][1]);
}

分析(贪心)

首先填入首尾,为了有最小值出现,同时将 1 填入。

还是一样从小到大填数,不过先考虑加上 \(a_i+c_i\),

其它数必然是接在中间,考虑直接用选完的数接上,

那么就是要找到 \(b_i-a_i\) 或者是 \(d_i-c_i\) 的最小值,用堆维护即可。


代码

#include <cstdio>
#include <cctype>
#include <cstring>
using namespace std;
const int N=5011; typedef long long lll;
int n,st,ed,x[N],Cnt; lll ans,heap[N<<1],a[4][N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void Swap(lll &x,lll &y){x^=y^=x^=y;}
void Push(lll W){
heap[++Cnt]=W;
for (int x=Cnt;x>1;x>>=1)
if (heap[x]<heap[x>>1])
Swap(heap[x],heap[x>>1]);
else return;
}
void Pop(){
heap[1]=heap[Cnt--];
for (int x=1;(x<<1)<=Cnt;){
int y=x<<1|1;
if (y>Cnt||heap[y]>=heap[y-1]) --y;
if (heap[x]<=heap[y]) return;
Swap(heap[x],heap[y]),x=y;
}
}
int main(){
n=iut(),st=iut(),ed=iut();
for (int i=1;i<=n;++i) x[i]=iut();
for (int i=1;i<=n;++i) a[0][i]=iut()+x[i];
for (int i=1;i<=n;++i) a[1][i]=iut()-x[i];
for (int i=1;i<=n;++i) a[2][i]=iut()+x[i];
for (int i=1;i<=n;++i) a[3][i]=iut()-x[i];
if (st>1&&ed>1) ans=a[2][st]+a[1][1]+a[3][1]+a[0][ed];
else ans=(st>ed)?(a[2][st]+a[1][ed]):(a[3][st]+a[0][ed]);
for (int i=2;i<=n;++i)
if (i==st) Push(a[3][i]-a[2][i]);
else if (i==ed) Push(a[1][i]-a[0][i]);
else{
ans+=a[0][i]+a[2][i];
if (i<st) Push(a[1][i]-a[0][i]);//可以与st接在一起
if (i<ed) Push(a[3][i]-a[2][i]);//可以与ed接在一起
ans+=heap[1],Pop();
if (i>st) Push(a[1][i]-a[0][i]);
if (i>ed) Push(a[3][i]-a[2][i]);
}
return !printf("%lld",ans);
}

#dp or 贪心+堆#CF704B Ant Man的更多相关文章

  1. 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)

    题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ...

  2. 【贪心+堆】XMU 1584 小明的烦恼

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1584 题目大意: 给n(n<=100 000)个任务的耗时和截至时间,问最少不能 ...

  3. BZOJ_2151_种树_贪心+堆+链表

    BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...

  4. BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表

    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...

  5. BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆

    BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是 ...

  6. 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆

    题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...

  7. 【bzoj1029】[JSOI2007]建筑抢修 贪心+堆

    题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建 ...

  8. 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆

    题目描述 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他.如果要满足顾客的需求,就必须要有足够的库存.问 ...

  9. BZOJ 1724: [Usaco2006 Nov]Fence Repair 切割木板 贪心 + 堆 + 反向思考

    Description Farmer John想修理牧场栅栏的某些小段.为此,他需要N(1<=N<=20,000)块特定长度的木板,第i块木板的长度为Li(1<=Li<=50, ...

  10. P1095 守望者的逃离——DP?贪心?

    https://www.luogu.org/problem/P1095 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大 ...

随机推荐

  1. Programming Abstractions in C阅读笔记:p293-p302

    <Programming Abstractions in C>学习第73天,p293-p302总结,总计10页. 一.技术总结 1.时间复杂度 (1)quadratic time(二次时间 ...

  2. Lua学习笔记之迭代器、table、模块和包、元表和协程

    迭代器 迭代器是一种对象,它能够来遍历标准库模板容器中的部分或全部元素,每个迭代器对象代表容器中确定的地址,在Lua中迭代器是一种支持指针类型的结构,他可以遍历集合的每一个元素. 泛型for迭代器 泛 ...

  3. ASP.NET XML序列化

    整理一下ASP.NET里面如何序列化实体为XML,获取解析XML内容为实体. 第一步要添加程序集引用,项目-->引用-->鼠标右键-->添加引用-->选择程序集-->Sy ...

  4. 云原生:使用HPA和VPA实现集群扩缩容

    1 背景 我们之前介绍过,随着业务流量上涨之后,我们的系统需要适时的进行扩容. 数据存储层我们也介绍过MySQL的扩容 Scale UP(纵向扩展) 和 Scale Out(横向扩展) 垂直拆分(Sc ...

  5. uniapp+定时云函数保活replit

    在replit中运行起来后,如果没有请求,则会在5分钟后关机,所以需要一个进程来定时访问一下,以达到保活的目的.replit是什么?我的理解是:它是一个在线的IDE,前端项目可以直接跑起来,且repl ...

  6. 使用Order By NULL 解决 group by后自动排序,优化Sql性能

    使用Order By NULL 解决 group by后自动排序,优化Sql性能 对于 Group by 后的结果,Mysql搜索引擎会将结果按照Group by 的字段按照升序,自动排序,例如: t ...

  7. 6. JVM本地方法

    1 本地方法 简单地讲,一个Native Method是一个Java调用非Java代码的接囗 一个Native Method是这样一个Java方法:该方法的实现由非Java语言实现,比如C. 这个特征 ...

  8. set中的erase使用的一个错误

    如果在遍历set的时候去erase很容易出事 事故代码: multiset<int>a; for(auto it=a.begin();it!=a.end();it++){ a.erase( ...

  9. CMAKE的学习

    下面我们来介绍Cmake Cmake 我们着重介绍一下CMAKE,是因为CMAKE现在用的人比MAKEFILE多一些,也更好理解,编写一些. 1 安装 cmake 1.1 卸载已经安装的旧版的CMAK ...

  10. 各种O总结及阿里代码规范总结

    首先梳理下POJO POJO包括 DO/DTO/BO/VO(所有的POJO类属性必须使用包装数据类型.) 定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值. controller使 ...