【GDOI2017第二轮模拟day2】开房间
来源:互联网 发布:淘宝如何晒单 编辑:程序博客网 时间:2024/06/09 15:34
Description
A君与B君正在玩一款闯关游戏,游戏共有n关,每一关的目标只有一个:开房间。
每一关都会有m个房间(从1~m进行编号),A君与B君每关各打开一个房间即可过关,但两人不能打开同一个房间。
通过每一关后,m个房间会重新关上,在第i关打开第j个房间需要消耗t[i][j]的体力值。并且无论A君还是B君,除了第一关外,若上一关自己开了a号房间,这一关开了b号房间,则需要额外消耗K*|a-b|点体力值。
现在请你回答,两人过完全部n关后,所要消耗的体力值之和(两人消耗体力相加)最小能是多少。
Input
第一行三个整数n,m,K.
接下来n行每行m个整数,第i行第j个整数t[i][j]表示第i关开第j个房间需要消耗的体力值。
Output
仅一行一个整数表示答案。
Sample Input
3 3 10
2 13 4
4 3 2
16 4 3
Sample Output
28
Data Constraint
30%的数据:n,m <= 5
60%的数据:n,m <= 50
100%的数据:1 <= n,m <= 300 , 1 <= K,t[i][j] <= 10^6
题解
一开始比赛的时候想到用堆把一个n优化成log,但是后来发现是道套路题
我们考虑f[z,i,j]的贡献,容易发现是左上,右上,左下,右下四个方向的f[z-1,x,y]+k*曼哈顿距离+a[z,i]+a[z,j],最后两项可以最后再加上去,而前面的两项可以发现是一个二维的前缀和,所以我们可以从四个方向预处理前缀和,然后就可以O(1)算出当前位置的答案了
但是这样还是会超时,然后我们发现两个人的路径不会出现交叉的情况,那么我们强制i小于j,然后就可以把常数缩小一半,可以通过此题~
贴代码
var f:array[0..305,0..305,0..305]of longint; a,p1,p2,p3,p4:array[0..305,0..305]of longint; i,j,k,l,n,m,x,y,z,ans:longint;function min(x,y:longint):longint;inline;begin if x<y then exit(x) else exit(y);end;begin assign(input,'room.in'); reset(input); assign(output,'room.out'); rewrite(output); readln(n,m,k); for i:=1 to n do begin for j:=1 to m do read(a[i,j]); readln; end; fillchar(f,sizeof(f),$7f); for i:=1 to m do for j:=1 to m do if i<>j then f[1,i,j]:=a[1,i]+a[1,j]; fillchar(p1,sizeof(p1),$7f); p2:=p1; p3:=p1; p4:=p1; for z:=2 to n do begin for i:=1 to m-1 do for j:=i+1 to m do begin if p1[i,j-1]<p1[i-1,j] then p1[i,j]:=p1[i,j-1]+k else p1[i,j]:=p1[i-1,j]+k; if f[z-1,i,j]<p1[i,j] then p1[i,j]:=f[z-1,i,j]; end; for i:=m-1 downto 1 do for j:=i+1 to m do begin p2[i,j]:=f[z-1,i,j]; p2[i,j]:=min(p2[i,j],k+min(p2[i+1,j],p2[i,j-1])); end; for i:=1 to m-1 do for j:=m downto i+1 do begin p3[i,j]:=f[z-1,i,j]; p3[i,j]:=min(p3[i,j],k+min(p3[i-1,j],p3[i,j+1])); end; for i:=m-1 downto 1 do for j:=m downto i+1 do begin p4[i,j]:=f[z-1,i,j]; p4[i,j]:=min(p4[i,j],k+min(p4[i+1,j],p4[i,j+1])); end; for i:=1 to m-1 do for j:=i+1 to m do begin //f[z,i,j]:=min(p1[i,j],min(p2[i,j],min(p3[i,j],p4[i,j]))); f[z,i,j]:=p4[i,j]; if p1[i,j]<f[z,i,j] then f[z,i,j]:=p1[i,j]; if p2[i,j]<f[z,i,j] then f[z,i,j]:=p2[i,j]; if p3[i,j]<f[z,i,j] then f[z,i,j]:=p3[i,j]; f[z,i,j]:=f[z,i,j]+a[z,i]+a[z,j]; end; end; ans:=maxlongint; for i:=1 to m do for j:=1 to m do if i<>j then ans:=min(ans,f[n,i,j]); writeln(ans); close(input); close(output);end.
- jzoj【GDOI2017第二轮模拟day2】开房间
- 【GDOI2017第二轮模拟day2】开房间
- 【GDOI2017第二轮模拟day2】开房间
- 【JZOJ5065】【GDOI2017第二轮模拟day2】开房间
- 【jzoj5065】【GDOI2017第二轮模拟day2】【开房间】【动态规划】
- jzoj 5065. 【GDOI2017第二轮模拟day2】开房间 动态规划
- 【GDOI2017第二轮模拟day2】中位数
- 【GDOI2017第二轮模拟day2】中位数
- 【JZOJ5066】【GDOI2017第二轮模拟day2】中位数
- GDOI2017第二轮模拟
- GDOI2017第二轮模拟总结
- GDOI2017模拟第二轮总结
- GDOI2017第二轮模拟总结
- GDOI2017模拟第二轮 4.15-4.17
- 【GDOI2017第二轮模拟day1】最长路径
- 【GDOI2017第二轮模拟day1】公路建设
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设
- 【jzoj5060】【GDOI2017第二轮模拟day1】【公路建设】【数据结构】
- VxWorks驱动程序开发指南--驱动程序的组织结构
- 理解进程调度时机跟踪分析进程调度与进程切换的过程
- Java高级深入与JVM
- Yum error – ImportError: No module named cElementTree
- uda1341之L3接口介绍
- 【GDOI2017第二轮模拟day2】开房间
- 从Chrome源码看JS Array的实现
- C++之智能指针
- 数据库管理
- Anaconda python版本的切换
- Linux下僵尸进程和孤儿进程模拟
- URAL 1993 This cheeseburger you don't need
- hmm
- ACM-动态规划1-最长上升子序列