[UVALive 3983] Robotruck
图片加载可能有点慢,请跳过题面先看题解,谢谢



设状态 \(f[i][j]\) 为,当前垃圾序号为 \(i\) ,当前承重为 \(j\) 的最小路程,好的这道题做完了
O(NC) G烂
$
$
我们这样设: \(f[i]\) 为,从起点出发,将前 \(i\) 个垃圾清完并放进垃圾桶的最小路程
显然有转移:\(f[i]=min(f[j]+H[j+1]+dis[j+1][i]+H[i]),j\le i,sum[j+1][i]<=c\),其中,
\(sum[i][j]\) 为第 \(i\) 个垃圾到第 \(j\) 个垃圾的重量和,\(H[i]\) 为垃圾 \(i\) 到原点的距离,\(dis[i][j]\) 为从第 \(i\) 个垃圾出发,依次经过第 \(i+1,i+2...j\) 个垃圾的总路程
我们将上面的式子转换一下,设 \(t[i]\) 为,从第 \(1\) 个垃圾出发,依次经过第 \(2,3,4...i\) 个垃圾的总路程,
则有:\(dis[i][j]=t[j]-t[i]\)
所以:\(f[i]=min(f[j]-t[j+1]+H[j+1])+t[i]+H[i],sum[j+1][i]<=c\)
令:\(calc(j)=f[j]-t[j+1]+H[j+1]\),所以有:\(f[i]=min(calc(j))+t[i]+H[i],sum[j+1][i]<=c\)
这个式子。。。用什么数据结构都能维护。。。\(XJB\) 搞一下就能 \(AC\) 了
$
$
这里用到单调队列,时间复杂度:\(O(n)\)
//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define N (100010)
#define il inline
#define RG register
using namespace std;
il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar();
if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; }
int T,n,c;
int x[N],y[N];
int t[N],S[N],H[N];
int que[N],f[N];
il void init(){
c=gi(),n=gi();
for(RG int i=1;i<=n;i++){
x[i]=gi(),y[i]=gi(); int w=gi();
H[i]=abs(x[i])+abs(y[i]);
t[i]=t[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
S[i]=S[i-1]+w;
}
}
il int calc(int x){return f[x]-t[x+1]+H[x+1];}
il void work(){
int hd=0,tl=0;
for(RG int i=1;i<=n;i++){
while(hd<=tl && S[i]-S[que[hd]]>c) hd++;
f[i]=calc(que[hd])+t[i]+H[i];
while(hd<=tl && calc(i)<=calc(que[tl])) tl--;
que[++tl]=i;
}
printf("%d\n",f[n]); if(T)puts("");
}
int main(){ T=gi(); while(T--){ init(); work(); } return 0; }
$
$
附,优先队列的代码,时间复杂度:\(O(nlogn)\)
//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#define N (100010)
#define il inline
#define RG register
using namespace std;
il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar();
if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; }
int T,n,c;
int x[N],y[N];
int t[N],S[N],H[N];
int f[N];
il void init(){
c=gi(),n=gi();
for(RG int i=1;i<=n;i++){
x[i]=gi(),y[i]=gi(); int w=gi();
H[i]=abs(x[i])+abs(y[i]);
t[i]=t[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
S[i]=S[i-1]+w;
}
}
struct R{int id,x;
il bool operator<(const R &a)const{return x>a.x;}
}a;
priority_queue<R>que;
il void work(){
while(!que.empty()) que.pop();
que.push(a);
for(RG int i=1;i<=n;i++){
R x=que.top();
while(!que.empty()&&S[i]-S[x.id]>c) que.pop(),x=que.top();
f[i]=x.x+t[i]+H[i];
que.push((R){i,f[i]-t[i+1]+H[i+1]});
}
printf("%d\n",f[n]); if(T)puts("");
}
int main(){ T=gi(); while(T--){ init(); work(); } return 0; }
$
$
另附,在vjudge上跑的比STL还慢的手写堆代码:
//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#define N (100010)
#define il inline
#define RG register
using namespace std;
il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar();
if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; }
int T,n,c;
int x[N],y[N];
int t[N],S[N],H[N];
int f[N],dis[N];
struct heap{
#define fa (x>>1)
#define ls (x<<1)
#define rs (x<<1|1)
int a[N],id[N],len;
il int top(){ return a[1]; }
il void push(RG int u){
if(!id[u]) id[u]=++len,a[len]=u; RG int x=id[u];
while(fa){
if(dis[a[x]]>=dis[a[fa]]) break;
swap(a[x],a[fa]),id[a[x]]=x,id[a[fa]]=fa,x=fa;
}
return;
}
il void pop(){
id[a[1]]=0,a[1]=a[len--]; if (len) id[a[1]]=1; RG int x=1,son;
while(ls<=len){
son=(rs<=len && dis[a[rs]]<dis[a[ls]]) ? rs : ls;
if(dis[a[x]]<=dis[a[son]]) break;
swap(a[x],a[son]),id[a[x]]=x,id[a[son]]=son,x=son;
}
return;
}
#undef fa
#undef ls
#undef rs
}que;
il void init(){
c=gi(),n=gi();
for(RG int i=1;i<=n;i++){
x[i]=gi(),y[i]=gi(); int w=gi();
H[i]=abs(x[i])+abs(y[i]);
t[i]=t[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
S[i]=S[i-1]+w;
}
}
il void work(){
while(que.len) que.pop();
que.push(0);
for(RG int i=1;i<=n;i++){
int x=que.top();
while(que.len&&S[i]-S[x]>c) que.pop(),x=que.top();
f[i]=dis[x]+t[i]+H[i];
dis[i]=f[i]-t[i+1]+H[i+1]; que.push(i);
}
printf("%d\n",f[n]); if(T)puts("");
}
int main(){ T=gi(); while(T--){ init(); work(); } return 0; }
[UVALive 3983] Robotruck的更多相关文章
- 【暑假】[深入动态规划]UVAlive 3983 Robotruck
UVAlive 3983 Robotruck 题目: Robotruck Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format ...
- UVALive 3983 Robotruck (单调队列,dp)
如果状态定义为序号和重量的话,决策就是下一个垃圾捡或者不减,但是状态数太多了. 如果只定义序号作为状态的话,决策就变成从前面的某个j一直捡到i才送回垃圾. 这就变成了一个区间选最小值的问题,用单调队列 ...
- UVaLive 3983 Robotruck (DP + 单调队列)
题意:有n个垃圾,第i个垃圾坐标为(xi,yi),重量为wi,有一个机器人,要按照编号从小到大的顺序剑气所有的垃圾兵扔进垃圾桶,垃圾桶在原点, 每次总重量不能超过C,两点间距离为曼哈顿距离,求出最短的 ...
- LA 3983 Robotruck
这道题感觉挺吃力的,还用到了我不熟悉的优先队列 题目中的推导也都看明白了,总之以后还要多体会才是 这里用优先对列的原因就是因为要维护一个滑动区间的最小值,比如在区间里2在1的前面,2在离开这个滑动区间 ...
- UVA LA 3983 - Robotruck DP,优先队列 难度: 2
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- UVALive 3983 捡垃圾的机器人 DP
这个题目我最初的做法沿用树形DP的做法,设置一个 dp[i][0]表示机器人在i点不回去的最短路径,dp[i][1]表示机器人在i点回去的最短路径,规划方向为i-1向i转移,结果发现这个不能用树形的结 ...
- 大白第一章第四节dp例题
入口 UVALive - 3882 #include<cstdio> using namespace std; ; int n,m,k,f[N]; int main(){ //f[i]表示 ...
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
随机推荐
- fiddler抓包工具教程
Fiddler是一个蛮好用的抓包工具,可以将网络传输发送与接受的数据包进行截获.重发.编辑.转存等操作.也可以用来检测网络安全.反正好处多多,举之不尽呀!当年学习的时候也蛮费劲,一些蛮实用隐藏的小功能 ...
- Haproxy介绍、安装与配置
Haproxy技术详解一. 介绍HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性.负载均衡,以及基于TCP和HTTP的应用程序代理.HAProxy特别适用于那些负载特大的web ...
- 用 Delphi 7 实现基于 FFMS2 的视频转 GIF 工具 [原创]
儿子经常要把自拍的视频(ts格式)转成表情包,下载了几个工具都不大好用,更多的还要收费.那就想自己写一个吧,没想到这一下断断续续地,居然 3 个月过去了.现在总算弄出个作品来了,结个贴吧.唉,天资愚钝 ...
- plsql 不修改tnsnames.ora文件
PLSQL 不修改tnsname直接连数据库的方式在PLSQL的Database中直接输入192.168.1.6:1521/VP.其中192.168.1.6为数据库的IP:1521为数据库端口:VP为 ...
- 20162314 Experiment 2 - Tree
Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...
- mysql 修改语句及耗时
1.含有某串字母的字段替换: update imagetable set imageID = replace(imageID, 'ZH0211001', 'ZH4111001') 只要imageID含 ...
- 第二阶段Sprint4
昨天:事实现保存到指定路径,并能够选择播放 今天:放弃改文件名,自动生成,实现暂停后继续录制 遇到的问题:不知道为什么实现不了,不然之前录制的视频就会丢失重新录
- thinkphp 学习1-模型
1.用M()方法创建模型类 $model = M("configsettings"); 2.使用find()方法或select()方法返回结果集 find()只返回一行记录,sel ...
- vue之Mutations 理解
commit:提交可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 stor ...
- grep文本处理工具
grep是一款文本过滤工具,基于正则表达式进行模式匹配sed:stream editor 流编辑器awk:linux上实现为gawk,文本报告生成器(格式化文本)文本搜索工具,根据用户指定的模式,对目 ...