jzoj【GDOI2017第二轮模拟day2】开房间
2017-04-16 20:53
295 查看
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
心情复杂,打了半天的题解死机一下全没了。。。
这题我讲一下思考过程,不想听的可以跳过。
所以容易得dp式子
f[i][j+1][k]=min(f[i][j+1][k],f[i][j][k]+c)(c即是参数,j
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 ; int a ; 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); }
相关文章推荐
- 【GDOI2017第二轮模拟day2】开房间
- 【jzoj5065】【GDOI2017第二轮模拟day2】【开房间】【动态规划】
- 【JZOJ5065】【GDOI2017第二轮模拟day2】开房间
- 【GDOI2017第二轮模拟day2】开房间
- 【GDOI2017第二轮模拟day2】中位数
- [jzoj5073 GDOI2017第二轮模拟] 影魔
- 【GDOI2017第二轮模拟day2】中位数
- 【JZOJ5066】【GDOI2017第二轮模拟day2】中位数
- 【JZOJ4925】【GDOI2017模拟12.18】稻草人
- JZOJ4753【GDOI2017模拟9.4】种树 LCT维护子树信息+换根时维护Dfs序(CC MONOPLOY加强版)
- GDOI2017第二轮模拟总结
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设
- 【省选专题一】图论 jzoj 5060.【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树+并查集
- JZOJ4843. 【GDOI2017模拟11.2】相位幻击
- 【JZOJ5324】【GDOI2017模拟8.21】麻将堆
- [jzoj5065][GDOI2017第二轮模拟day two] 开房
- 【JZOJ5061】【GDOI2017第二轮模拟day1】最长路径
- JZOJ4779 【GDOI2017模拟9.14】鞍点(OICamp 2016 Day 5 T1) 计数问题
- JZOJ4796 【GDOI2017模拟9.21】三色图 构造可行解
- JZOJ4800. 【GDOI2017模拟9.24】周末晚会