算法笔记/USACO Guide GOLD金组DP 3. Paths on Grids

今天学习背包DP(Knapsack DP) 

是USACO Guide的DP章节中第三点

What is grid DP? -Summary

DP problems often involve a 2D grid where paths are analyzed. Movement is restricted to one direction on the x-axis and y-axis, typically starting from one corner and ending at another. The goal may be to count paths or find max/min values. Sub-problems are sub-rectangles of the grid. For instance, to count paths from 1,1 to N,M moving positively, we define dp[x][y] as the number of paths to x,y. The recurrence relation is dp[x][y] = dp[x-1][y] + dp[x][y-1], with dp[1][1] = 1. Understanding cell appending aids in forming the correct recurrence.

简单来说,DP 问题通常涉及分析路径的时候使用2D的数组。移动仅限于 x 轴和 y 轴上的一个方向,通常从一个角开始并在另一个角结束。目标可能是对路 径进行计数或查找最大/最小值。子问题是网格的子矩形。例如,为了计算从 1,1 到 N,M 正向移动的路径,我们将 dp[x][y] 定义为到 x,y 的路径数。递推关系为 dp[x][y] = dp[x-1][y] + dp[x][y-1],其中 dp[1][1] = 1。理解单元格附加有助于形成正确的规律。

代表题目Grip Paths

Consider an n×n grid whose squares may have traps. It is not allowed to move to a square with a trap.

Your task is to calculate the number of paths from the upper-left square to the lower-right square. You can only move right or down.

Input

The first input line has an integer n: the size of the grid.

After this, there are nnn lines that describe the grid. Each line has n characters: . denotes an empty cell, and * denotes a trap.

Output

Print the number of paths modulo 10^9+7 

Constraints

  • 1≤n≤1000 

Example

Input:

4
....
.*..
...*
*...

Output:

3
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

bool ok[1000][1000];
ll dp[1000][1000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < n; j++) {
			if (s[j] == '.') ok[i][j] = true;
			else ok[i][j] = false;
		}
	}

	dp[0][0] = 1;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (!ok[i][j]) dp[i][j] = 0;
			else {
				if (i > 0) dp[i][j] += dp[i - 1][j];
				if (j > 0) dp[i][j] += dp[i][j - 1];
				dp[i][j] %= 1000000007;
			}
		}
	}

	cout << dp[n - 1][n - 1] << "\n";

	return 0;
}

思路

In this problem, we are directly given a 2D grid of cells, and we have to count the number of paths from corner to corner that can only go down (positive yyy direction) and to the right (positive xxx direction), with a special catch. The path can't use a cell marked with an asterisk.

We come close to being able to use our original recurrence, but we have to modify it. Basically, if a cell (x,y)(x, y)(x,y) is normal, we can use the recurrence normally. But, if cell (x,y)(x, y)(x,y) has an asterisk, the dp-value is 000, because no path can end on a trap.

在这个问题中直接给我们了一个2D元网格,我们必须用一个特殊的判断方法计算从一个角落到另一个角落只能向下的路径数量(正 y方向)和向右(正 x 方向)。这路径不能使用标有星号的单元格。

我们已经接近能够使用原来的递归方式了,但是我们必须修改它。简单来速回,如果一个单元格 (x, y) 是正常的,我们可以使用递归通常情况下。但是,如果单元格 (x, y) 有星号,则 dp 值为 0,因为没有路径可能以陷阱(*)结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值