[CSP-J2020] 方格取数

CSP-J2020方格取数的动态规划解法

题目

1
2

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,m,
	d[N][N];//方格数 
long long int fa[N][N],//从左和从上过来,找最大 
	fb[N][N],//从左过来和从下过来,找最大 
	f[N][N];//最大和 
	
int main(){
	//freopen("data.cpp","r",stdin);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)cin>>d[i][j];//每个格子的数值,可能是负值 
	for(int i=0;i<=n+1;i++)
	for(int j=0;j<=m+1;j++)fa[i][j]=fb[i][j]=f[i][j]=LLONG_MIN;//要找最大,所以不能初始为0 
	f[1][1]=d[1][1];//从左上出发 
	for(int i=2;i<=n;i++)f[i][1]=f[i-1][1]+d[i][1];//不能往左,第一列只能往下 
	for(int j=2;j<=m;j++){//解决剩余列 
		for(int i=1;i<=n;i++)fa[i][j]=max(fa[i-1][j],f[i][j-1])+d[i][j];//每列往右往下的最大 
		for(int i=n;i>=1;i--)fb[i][j]=max(fb[i+1][j],f[i][j-1])+d[i][j];//每列往右往上的最大 
		for(int i=1;i<=n;i++)f[i][j]=max(fa[i][j],fb[i][j]);//留下更大的 
	}
	cout<<f[n][m];
	return 0;
}

分析

  • 从左上出发往右下,可右、可上、可下,单元格数值可能是负,求最大路径和。
  • 通过定义状态数组,记录到达每个格子的最大路径和,利用子问题的最优解推导出全局最优解。
  • 状态f[i][j]每个格子的最大路径和,辅助数组fa[i][j]每个格子从左和从上过来的最大路径和,辅助数组fb[i][j]每个格子从左和从下过来的最大路径和。
  • 状态转移
  • 初始状态,f[1][1]=d[i][j]出发格子,其他都是从该格子推算。所以第一列直接求出。每个格子都可能是负数,所以找最大值不能跟0比较,要跟最小比LLONG_MIN.
  • 时间复杂度,共m列,每列三次n循环,所以是O(N*M)=106 <108
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值