捡两次废纸(DP)



问题

 

捡两次废纸

 

当前有M * N格子构成的城市。这城市各处都有垃圾。

范贤捡废纸是从最左上角的格子(1, 1)出发移动到最右下角的 (M, N) ,这时需要走最短的路径。即,只能移动到相邻的向右或向下的格子。

在这里要进一步重新从 (M, N)移动到 (1, 1)再次捡废纸。这时也要走最短的路径。即,只能移动到相邻的向左或向上的格子。

需要注意的是捡完一次废纸就再没有废纸了。

这时,请输出范贤能收集到的废纸量的最大值。

 

输入

 

第一行给出测试用例个数T(1 ≤ T ≤ 20)

每个测试用例的第一行给出N, M(2 ≤ N, M ≤ 100)。下一个M行,每行给出N个字符。

'*'是表示可以行走的有废纸的地方。

'.'是表示可以行走,但没有废纸的地方。

'#'是表示不能行走的地方。

当前已确定(1, 1) (M, N)是可以去的地方。

还有确定两点之间有路径。

 

输出

 

每个测试用例,通过一行输出范贤可以捡到的最多废纸量。

案例输入

2

9 7

*........

.....**#.

..**...#*

..####*#.

.*.#*.*#.

...#**...

*........

5 5

.*.*.

*###.

*.*.*

.###*

.*.*.

案例输出

7

8

案例补充

在第一个测试用例中, 范贤到达 (M, N)位置时,城市变成如下:

xxxxx....

....xxx#.

..**..x#*

..####x#.

.*.#*.x#.

...#**xxx

*.......x

X表示范贤的移动路径。现在为止收集的废纸是5个。重新移动到 (1, 1)时,城市变成如下:

yxxxx....

y...xxx#.

yyyyyyy#*

..####y#.

.*.#*.y#.

...#**yxx

*.....yyy

Y表示范贤的移动路径。范贤收集的总废纸量为7个,所以输出7

第二个测试用例的解,如下所示:

yxxxx

y###x

y.*.x

y###x

yyyyy

 

#include <stdio.h>
#include <string.h>
#include <algorithm>

int Dp[210][110][110], W, H;
char ch[110];
bool inp[110][110];
bool itr[110][110];

int main()
{
	int T; scanf("%d", &T);
	while (T--){
		memset(Dp, 0, sizeof Dp);
		memset(inp, 0, sizeof inp);
		memset(itr, 0, sizeof itr);
		int i, j, k;
		scanf("%d%d\n", &W, &H);
		for (i = 1; i <= H; i++){
			scanf("%s", ch);
			for (j = 1; j <= W; j++){
				if (ch[j - 1] != '#')inp[i][j] = true;
				if (ch[j - 1] == '*')itr[i][j] = true;
			}
		}
		for (i = 2; i <= W + H; i++){
			for (j = 1; j<i; j++){
				if (j>H || i - j>W || !inp[j][i - j])continue;
				for (k = j; k<i; k++){
					if (k>H || i - k>W || !inp[k][i - k])continue;
					int t = 0;
					t = std::max(std::max(Dp[i - 1][j - 1][k], Dp[i - 1][j][k]), std::max(Dp[i - 1][j - 1][k - 1], Dp[i - 1][j][k - 1]));
					Dp[i][j][k] = (j == k ? itr[j][i - j] : itr[j][i - j] + itr[k][i - k]) + t;
				}
			}
		}
		printf("%d\n", Dp[W + H][H][H]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值