【集训DAY12】Bee GO!【动态规划】【数学】

119 篇文章 0 订阅
96 篇文章 0 订阅

在这里插入图片描述

思路:

我们发现它肯定是走到一个点然后在两个点之间来回走,所以我们设f[i][j]表示走到i,j的路径长度,然后转移m*n次(就可以走到地图每一个点),然后贪心选择每个点相邻的点中权值最大的那一个来回走就行了。

c o d e code code

#include<iostream>
#include<cstdio>
 
#define re register
#define ll long long
 
using namespace std;

const ll MAXN = 110;
 
ll n, m, A, B, k, ans = -1e18;
ll f[MAXN][MAXN], g[MAXN][MAXN], a[MAXN][MAXN];
bool v[MAXN][MAXN], v1[MAXN][MAXN];

int main() {
//	freopen("maja.in", "r", stdin);
//	freopen("maja.out", "w", stdout);
	scanf("%lld%lld%lld%lld%lld", &n, &m, &A, &B, &k);
	for(re ll i = 1; i <= n; ++ i)
 		for(re ll j = 1; j <= m; ++ j)
 			scanf("%lld", &a[i][j]);
	for(re ll i = 0; i <= n + 1; i ++)
		for(re ll j = 0; j <= m + 1; j ++) g[i][j] = 0;
 	g[A][B] = 0, v1[A][B] = 1, v[A][B] = 1;
	for(re ll len = 1; len <= n * m; ++ len) {
 		if(len * 2 > k) break;
		for(re ll i = 1; i <= n; ++ i)
 			for(re ll j = 1; j <= m; ++ j) {
 				if(i > 1 && v1[i - 1][j] != 0) f[i][j] = g[i - 1][j] + a[i][j], v[i][j] = 1;
				if(i < n && v1[i + 1][j] != 0) f[i][j] = max(f[i][j], g[i + 1][j] + a[i][j]), v[i][j] = 1;
 				if(j > 1 && v1[i][j - 1] != 0) f[i][j] = max(f[i][j], g[i][j - 1] + a[i][j]), v[i][j] = 1;
				if(j < m && v1[i][j + 1] != 0) f[i][j] = max(f[i][j], g[i][j + 1] + a[i][j]), v[i][j] = 1;
 			}
		for(re ll i = 1; i <= n; ++ i) 
			for(re ll j = 1; j <= m; ++ j) {
				v1[i][j] = v[i][j] | v1[i][j];
				v[i][j] = v1[i][j];
				if(v[i][j] == 1) g[i][j] = f[i][j];
 				ll p = 0;
				p = max(a[i + 1][j], max(a[i - 1][j], max(a[i][j + 1], a[i][j - 1])));
				if(v[i][j] == 1) ans = max(ans, f[i][j] * 2 - a[i][j] * 1 + (k - len * 2) / 2 * (a[i][j] + p));
			}
   	}
	printf("%lld", ans);
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值