jzoj【GDOI2017第二轮模拟day2】开房间
来源:互联网 发布:疯狂联盟兵种数据 编辑:程序博客网 时间:2024/04/27 21:59
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
心情复杂,打了半天的题解死机一下全没了。。。
这题我讲一下思考过程,不想听的可以跳过。
首先我们很容易想到列出f[i][j][k]表示已经走完前i-1层,走到第i层,A走j,B走k的方案数。然后我们先无脑暴力一波,直接枚举从上一层的j,k跳到这层的j'k',复杂度nm^4。60分都没有,明显不行。那么我们就致力于减少枚举的次数,最好能达到nm^2。 要减少,也就是说,我们目前枚举的有两个数是没用的,或者能替代掉,才能去。那么,对于上一层的位置j,k,明显是不能去掉的的,因为我们并不能确定当前位置的上一个状态。那么我们只能去掉对于当前第i层的枚举了。怎么替代呢,我们想想,如果我们必须枚举这一层,是因为我们不能确定,从上一层的j,k位置,走最优方案,到这一层是哪一个位置。但是明显,我们是可以不用确认的,因为我们对于每一个位置j',更新j',j'+1,j'-1(下一层),就可以把状态算上, 这什么意思呢?我举个例子:比如我们一开始更新了f[i][1][2],(j'=1,k'=2)f[i][1][3].....(i!=1),然后我们更新到f[i][1][3](j'=2,k'=3),此时更新的时候,已经把上一个状态累积进去了,用这种方法,我们就可以成功将dp复杂度缩小到nm^2.
所以容易得dp式子
f[i][j+1][k]=min(f[i][j+1][k],f[i][j][k]+c)(c即是参数,j
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;ll inf=1e15;int n,m;const int N=305;ll f[N][N];int a[N][N];int c;int main(){ freopen("room.in","r",stdin); freopen("room.out","w",stdout); scanf("%d%d%d",&n,&m,&c); fo(i,1,n) { fo(j,1,m) scanf("%d",&a[i][j]); } fo(i,1,m) fo(j,1,i-1)f[i][j]=a[1][i]+a[1][j]; fo(i,2,n) { //memcpy(f[i],f[i-1],sizeof(f[i])); fo(j,1,m) fo(k,1,j-1) { if (j+1<=m) f[j+1][k]=min(f[j+1][k],f[j][k]+c); if (k+1<=m) f[j][k+1]=min(f[j][k+1],f[j][k]+c); } fd(j,m,1) fd(k,j-1,1) { if (j-1>=1) f[j-1][k]=min(f[j-1][k],f[j][k]+c); if (k-1>=1) f[j][k-1]=min(f[j][k-1],f[j][k]+c); } fo(j,1,m) fo(k,1,j-1) f[j][k]+=a[i][j]+a[i][k]; } ll ans=inf; fo(i,1,m) fo(j,1,i-1)ans=min(ans,f[i][j]); printf("%lld\n",ans);}
0 0
- jzoj【GDOI2017第二轮模拟day2】开房间
- jzoj 5065. 【GDOI2017第二轮模拟day2】开房间 动态规划
- 【GDOI2017第二轮模拟day2】开房间
- 【GDOI2017第二轮模拟day2】开房间
- 【JZOJ5065】【GDOI2017第二轮模拟day2】开房间
- 【jzoj5065】【GDOI2017第二轮模拟day2】【开房间】【动态规划】
- 【GDOI2017第二轮模拟day2】中位数
- 【GDOI2017第二轮模拟day2】中位数
- 【JZOJ5066】【GDOI2017第二轮模拟day2】中位数
- GDOI2017第二轮模拟
- GDOI2017第二轮模拟总结
- GDOI2017模拟第二轮总结
- GDOI2017第二轮模拟总结
- jzoj 5060. 【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
- jzoj 5061. 【GDOI2017第二轮模拟day1】最长路径 动态规划
- GDOI2017模拟第二轮 4.15-4.17
- 【GDOI2017第二轮模拟day1】最长路径
- 【GDOI2017第二轮模拟day1】公路建设
- C++学习笔记:基础知识
- 联网在线毁了《模拟城市5》!打造自己的城市不需要网络
- Shodan
- 初识 Vim ,未来的路还很长
- js闭包初探
- jzoj【GDOI2017第二轮模拟day2】开房间
- 1013. 数素数 (20)
- poj 2182 线段树
- 了解嵌入式操作系统
- Android性能优化 (1)—— 内存溢出和内存泄漏的介绍
- Android 随笔——下载图片
- 自考结束,细数点滴
- android让控件基于底部
- 3360 学生信息的添加与查询