行程得分
2016-07-06 18:22
169 查看
行程得分
题目描述
BSNY设计了一个游戏,在一个n*m的网格中,游戏者要从(1,1)走到(n,m)。每个格子有一个数字,游戏者每到一个格子,得分就会加上格子上的分数,初始得分为0。但这个分数有正有负:如果是正数,游戏者加上这个分数,但此时格子的分数会变相反数,下一次再到这个格子,这个分数就是负数了。
如果是负数,游戏者加上这个分数,之后再到这个格子也一样。
如果是0,不增也不减。
游戏者只能向左,向右,向下移动,不能向上移动。
问,从(1,1)到(n,m)最大可以得多少分?
输入
输入n, m然后输入n*m的矩阵
输出
输出最大得分样例输入
2 32 -1 3
3 1 -1
样例输出
5【样例说明】
2到-1到3到-1,然后向下走,到1到3到-1到-1
得分为2-1+3-1+1+3-1-1=5
【数据规模和约定】
1<=n, m<=200
-1000<= 格子的分数 <=1000
题解:
因为不能向上走,所以这还是很明显的DP题。
我们定义f[i][j]表示前i行,BSNY在第i行第j个结束(即进入下一行)
那么转移就很简单了,f[i][j]=f[i-1][k]+pre[i][k][j]
pre[i][k][j]表示在第i行,从k点走到j点可以得到的最大值。
现在的难点就在于求这个pre数组了,怎么把它预处理出来呢???
仔细考虑题目,还是能发现一些特性的,比如一个点最多经过3次;
考虑从一个点出发再回到本身,一共有3种情况
1.不走
2.向左或是向右到某个点,再回来
3.先向左走到某个点,再往右走到某个点,最后再向右返回
假如这种情况回来,从k点到j点也是差不多的。
接下来就只剩下把模拟的这个过程的值计算出来了。。
加一下我的方法:
l[i][j]表示第i行的第j个点,向左走并回到原点的最大值。
r[i][j]表示第i行的第j个点,向右走并回到原点的最大值。
中间的片段和也是可以预处理的,注意一下正数走过之后变负这个情况。
#include<stdio.h> #include<iostream> #include<stdlib.h> using namespace std; const int N=205; int n,m,i,j,k,a ,s ,sum ,f ,l ,r ,pre ; int main() { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); if(a[i][j]<=0) s[i][j]=s[i][j-1]+a[i][j]*2;else s[i][j]=s[i][j-1]; sum[i][j]=sum[i][j-1]+a[i][j]; } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(a[i][j]<=0) l[i][j]=r[i][j]=a[i][j]*2;else l[i][j]=r[i][j]=0; for(k=j+1;k<=m;k++) r[i][j]=max(r[i][j],a[i][k]+s[i][k-1]-s[i][j-1]); for(k=j-1;k>=1;k--) l[i][j]=max(l[i][j],a[i][k]+s[i][j]-s[i][k]); } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) for(k=j;k<=m;k++) { pre[j][k]=-1e8; pre[j][k]=max(pre[j][k],sum[i][k]-sum[i][j-1]); pre[j][k]=max(pre[j][k],l[i][j]+sum[i][k]-sum[i][j]); pre[j][k]=max(pre[j][k],r[i][k]+sum[i][k-1]-sum[i][j-1]); if(j==k&&a[i][j]<=0) pre[j][k]=max(pre[j][k],l[i][j]+r[i][k]+abs(a[i][j]));else if(j==k&&a[i][j]>0) pre[j][k]=max(pre[j][k],l[i][j]+r[i][k]-abs(a[i][j]));else pre[j][k]=max(pre[j][k],l[i][j]+r[i][k]+sum[i][k-1]-sum[i][j]); pre[k][j]=pre[j][k]; } for(j=1;j<=m;j++) { if(i==1) { f[i][j]=pre[1][j]; continue; } f[i][j]=-1e8; for(k=1;k<=m;k++) f[i][j]=max(f[i][j],f[i-1][k]+pre[k][j]); } } cout<<f [m]; return 0; }
相关文章推荐
- mac上brew使用
- 使用PyCharm配置Spark的Python开发环境(基础)
- UIWebView的js与native代码的交互
- PHP5.6.15连接Sql Server 2008配置方案
- AngularJS Tutorial (2)
- Java如何取得当前程序部署的服务器的IP
- 移花接木-联想Ideapad Y570 USB2.0升级到USB3.0成功
- GitHub 优秀的 Android 开源项目
- Retrofit+MVP模式学习
- centos yum安装memcached及php memcache扩展
- Windows Error Code(windows错误代码详解)
- 使用uwsgi 部署python web服务
- GCC优化选项简单说明
- Javascript 基础汇总
- iOS自定义导航栏,侧滑返回卡死情况的解决办法
- 慎用$rootScope
- push 到下一界面明显卡顿的现象
- MPV 播放器 设置默认播放器 cmd + i
- java用缓冲区读取文件
- DOM 扩展 Selectors API