[ABC147E] Balanced Path

该篇文章讨论了如何使用动态规划方法解决一个关于在网格中行走的问题,通过计算不同涂色方案下黑色和红色数字之和的差值,找到使差值最小的策略。
摘要由CSDN通过智能技术生成
题目描述

给定 n 行,m 列的网格。第i行第j个格子上面写有两个数字 A[i][j] 和 B[i][j] 。
邱宇将从左上角走到右下角(第一行第一列走到第n行第m列),每次只能往下走一行或者往右走一格且不能走出去。在每一个格子上,他将给A[i][j]和B[i][j]一个涂成红色,另一个填黑色。
在所有有可能的路径与涂色方案中,abs(黑色数字之和-红色数字之和)最小是多少?

输入

第一行两个正整数表示行和列n,m
接下来n行,每行m个数表示格子上的数字A[i][j]
接下来又有n行,每行m个数表示格子上的数字B[i][j]
数据保证2 <= n,m <= 80,0 <= A[i][j], B[i][j] <= 80

输出

输出最小的两种颜色数字之和的差值。

样例输入
样例输入1:
2 2
1 2
3 4
3 4
2 1
样例输入2:
2 3
1 10 80
80 10 1
1 2 3
4 5 6

 样例输出

样例输出1:
0
样例输出2:
2
题解
#include<bits/stdc++.h>
using namespace std;
bool dp[81][81][25601];
int h,w;
int a[85][85],b[85][85],c[85][85];
int sum;
int main()
{
	cin>>h>>w;
	for(int i=1;i<=h;++i)
	{
		for(int j=1;j<=w;++j)
		{
			cin>>a[i][j];
			sum=max(sum,a[i][j]);
		}
	}
	for(int i=1;i<=h;++i)
	{
		for(int j=1;j<=w;++j)
		{
			cin>>b[i][j];
			c[i][j]=a[i][j]-b[i][j];
		}
	}
       //初始值
	dp[1][1][c[1][1]+12800]=1;
	dp[1][1][-c[1][1]+12800]=1;
	for(int i=1;i<=h;++i)
	{
		for(int j=1;j<=w;++j)
		{
			for(int k=0;k<=sum*(h+w-1);++k)
			{
                              //状态转移,记得加上 12800
				dp[i][j][k+12800]|=dp[i-1][j][k+c[i][j]+12800]|dp[i-1][j][k-c[i][j]+12800];
				dp[i][j][k+12800]|=dp[i][j-1][k+c[i][j]+12800]|dp[i][j-1][k-c[i][j]+12800];
				dp[i][j][-k+12800]|=dp[i-1][j][-k+c[i][j]+12800]|dp[i-1][j][-k-c[i][j]+12800];
				dp[i][j][-k+12800]|=dp[i][j-1][-k+c[i][j]+12800]|dp[i][j-1][-k-c[i][j]+12800];
			}
		}
	}
	for(int i=0;i<=sum*(h+w-1);++i)
	{
		if(dp[h][w][i+12800]||dp[h][w][-i+12800])
		{
        		//找到最小的k的值
			cout<<i<<endl;
			return 0;
		}
	}
	return 0;
}

很简单的入门题

动态规划 dp。

我们定义 dp[i][j][k] 表示到达 i,j 点是否可以做到 涂成红色减去涂成蓝色得数的值 为 k,可以做到则为 11,不可以做到就是 00。然后我们在定义一个 c[i][j] 表示 a[i][j]−b[i][j]。

显然,我们可以得到两种大的情况。

第一种,从i−1,j 走过来,则此时可以得到转移方程为 dp[i][j][k]∣=dp[i−1][j][k−c[i][j]]∣dp[i−1][j][k+c[i][j]]。

第二种,从 i,j−1 走过来,则此时同上,可以得到转移方程为 dp[i][j][k]∣=dp[i][j−1][k−c[i][j]]∣dp[i][j−1][k−c[i][j]]。

但是这个地方我们从要注意一种情况,就是有可能这个值为负数,所以,我们可以将所有的数组多开一倍,然后我们将所有的 k 加上一个 1280012800,就不会存在有负数的情况了。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非黑皆白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值