题目链接:http://codeforces.com/problemset/problem/429/B

题目大意:两个人(假设为A,B),打算健身,有N行M列个房间,每个房间能消耗Map[i][j]的卡路里,A起点为(1,1)要达到(n,m)点,且每次只能向右走一步或向下走一步,

B起点为(n,1),要达到(1,m),且每次只能向上走一步,或向右走一步。有要求A,B必须在某一个房间相遇一次,且A,B在该房间不再消耗卡路里,因为两人锻炼身体的速度不同,

所以在相遇时经过的房间数亦可能不相同。问两人合计最多消耗多少卡路里。

解题思路:

先预处理四个dp数组:

dp1[i][j]表示从(1,1)到(n,m)路程中,(1,1)到(i,j)的最优解

dp2[i][j]表示从(1,1)到(n,m)路程中,(i,j)到(n,m)的最优解

dp3[i][j]表示从(n,1)到(1,m)路程中,(n,1)到(i,j)的最优解

dp4[i][j]表示从(n,1)到(1,m)路程中,(i,j)到(1,m)最优解

由于两人只能相遇一次,若两人相遇则肯定会是以下两种情况(蓝色表示A可能经过的区域,红色表示B可能经过的区域,紫色为相遇点):

那么对应上图两种情况分别有:

t1=dp1[i][j-1]+dp2[i][j+1]+dp3[i+1][j]+dp4[i-1][j];//情况一

t2=dp1[i-1][j]+dp2[i+1][j]+dp3[i][j-1]+dp4[i][j+1];//情况二

所以我们只要枚举点(i,j)即可,注意1<i<n且1<j<n否则不符合上图的情况。

代码:

 #include<bits/stdc++.h>
#define lc(a) (a<<1)
#define rc(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define _for(i,start,end) for(int i=start;i<=end;i++)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long LL;
const int N=1e3+;
const int INF=0x3f3f3f3f;
const double eps=1e-; int mp[N][N];
LL dp1[N][N],dp2[N][N],dp3[N][N],dp4[N][N]; int main(){
FAST_IO;
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)
cin>>mp[i][j];
}
//计算从(1,1)到(n,m)路程中,(1,1)到(i,j)的最优解
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
dp1[i][j]=max(dp1[i-][j],dp1[i][j-])+mp[i][j];
}
}
//计算从(1,1)到(n,m)路程中,(i,j)到(n,m)的最优解
for(int i=n;i>=;i--){
for(int j=m;j>=;j--){
dp2[i][j]=max(dp2[i+][j],dp2[i][j+])+mp[i][j];
}
}
//计算从(n,1)到(1,m)路程中,(n,1)到(i,j)的最优解
for(int i=n;i>=;i--){
for(int j=;j<=m;j++){
dp3[i][j]=max(dp3[i+][j],dp3[i][j-])+mp[i][j];
}
}
//计算从(n,1)到(1,m)路程中,(i,j)到(1,m)最优解
for(int i=;i<=n;i++){
for(int j=m;j>=;j--){
dp4[i][j]=max(dp4[i-][j],dp4[i][j+])+mp[i][j];
}
} LL ans=-;
//枚举相遇点,注意不能在边界相遇,因为这样两个人相遇肯定不止一次
for(int i=;i<n;i++){
for(int j=;j<m;j++){
LL t1=dp1[i][j-]+dp2[i][j+]+dp3[i+][j]+dp4[i-][j];//情况一
LL t2=dp1[i-][j]+dp2[i+][j]+dp3[i][j-]+dp4[i][j+];//情况二
ans=max(ans,max(t1,t2));
}
}
cout<<ans<<endl;
return ;
}

Codeforces 429B Working out(递推DP)的更多相关文章

  1. Code Force 429B Working out【递推dp】

    Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the ...

  2. 递推DP URAL 1167 Bicolored Horses

    题目传送门 题意:k个马棚,n条马,黑马1, 白马0,每个马棚unhappy指数:黑马数*白马数,问最小的unhappy值是多少分析:dp[i][j] 表示第i个马棚放j只马的最小unhappy值,状 ...

  3. 递推DP URAL 1017 Staircases

    题目传送门 /* 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 状态转 ...

  4. 递推DP URAL 1260 Nudnik Photographer

    题目传送门 /* 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 */ #include <cstdio> #include <algorithm> ...

  5. 递推DP URAL 1353 Milliard Vasya's Function

    题目传送门 /* 题意:1~1e9的数字里,各个位数数字相加和为s的个数 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 状态转移方程:dp[i][j] += dp[i-1][j-k] ...

  6. 递推DP URAL 1119 Metro

    题目传送门 /* 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 递推DP:仿照JayYe,处理的很巧妙,学习:) 好 ...

  7. 递推DP 赛码 1005 Game

    题目传送门 /* 递推DP:官方题解 令Fi,j代表剩下i个人时,若BrotherK的位置是1,那么位置为j的人是否可能获胜 转移的时候可以枚举当前轮指定的数是什么,那么就可以计算出当前位置j的人在剩 ...

  8. 递推DP HDOJ 5328 Problem Killer

    题目传送门 /* 递推DP: 如果a, b, c是等差数列,且b, c, d是等差数列,那么a, b, c, d是等差数列,等比数列同理 判断ai-2, ai-1, ai是否是等差(比)数列,能在O( ...

  9. hdu1978(递推dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1978 分析: 递推DP. dp[][]表示可以到达改点的方法数. 刚开始:外循环扫描所有点dp[x][ ...

  10. 递推DP URAL 1031 Railway Tickets

    题目传送门 /* 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 注意:s1与s2大小不一定,坑! 详细解释:http://blog.csdn.net/kk303/article/d ...

随机推荐

  1. 解决Android SDK Manager更新时出现问题

    使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xm ...

  2. Android Intent 总结

    //打开指定网页Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.goo ...

  3. Android自定义 Dialog 对话框

    Android自定义Dialoghttp://www.cnblogs.com/and_he/archive/2011/09/16/2178716.html Android使用自定义AlertDialo ...

  4. ubuntu vim 配置

    set nuset autoindent cindentmap<F9> :w<cr> :!g++ -O2 -o %< % -Wall<cr>map<F1 ...

  5. 彻底理解 Python 生成器

    1. 生成器定义 在Python中,一边循环一边计算的机制,称为生成器:generator. 2. 为什么要有生成器 列表所有数据都在内存中,如果有海量数据的话将会非常耗内存. 如:仅仅需要访问前面几 ...

  6. django中的转义

    什么是html转义? 所谓html转义就是将  html关键字(包括标签,特殊字符等)  进行过滤替换.过滤替换格式如下: 接下来我们通过实例演示django中转义的细节以及如何关闭转义 一  dja ...

  7. LINUX 线程

    1.使用进程技术的优势(1)CPU时分复用,单核心CPU可以实现宏观上的并行(2)实现多任务系统需求(多任务的需求是客观的)2.进程技术的劣势(1)进程间切换开销大(2)进程间通信麻烦而且效率低3.解 ...

  8. group by实现原理及其作用

    mysql中group by实现方式有三种,松散索引,紧凑索引,临时文件(文件排序). 在网上看了相关的介绍,大部分介绍都比较晦涩难懂,这里说下我的理解. 在学习SQL优化时,我们都知道可以对grou ...

  9. gson转换对象为json字符串时对特殊字符编码的问题

    使用google的gson进行object和json的转换,如下: public static String object2json(Object obj) { Gson gson = new Gso ...

  10. 【学习笔记】FreeMarker 之于Servlet与Stuts2的应用

    FreeMarker应用在Servlet(0配置web.xml形式): 准备环境: tomcat7.eclipse最新版.jdk1.8.freemarker v2.3.20.jar 举例项目结构图: ...