世 上 没 有 绝 望 的 处 境
只 有 对 处 境 绝 望 的 人
Atcoder-Queen on Grid
Problem Statement
We have a grid with H horizontal rows and W vertical columns of squares.Square (i,j), which is at the i-th row from the top and j-th column from the left, is wall if Sij is
#
and road if Sij is.
There is a queen, the chess piece, at Square (1,1). In one move, it can move any number of squares to the right, downwards, or diagonally to the lower right to a road square without jumping over wall squares.
In how many ways can the queen travel from Square (1,1) to Square (H,W)? Find the count modulo 109+7.Here, two ways to travel are considered different if and only if there exists i such that the position of the queen after the i-th move is different in those two ways.
Constraints
2 ⩽ H,W ⩽ 2000
Sij is#
or.
Sij and Sij are.
Input
Input is given from Standard Input in the following format:
H WS11…S1w
.
.
SH1…SHW
Output
Print the number of ways, modulo 19+7, in which the queen can travel from Square (1,1) to Square <H,W>.
Sample Input 1
3 3
...
.#.
...
Sample Output 1
10
There are 10 ways to travel, as follows:
(1,1)→(1,2)→(1,3)→(2,3)→(3,3)
(1,1)→(1,2)→(1,3)→(3,3)
(1,1)→(1,2)→(2,3)→(3,3)
(1,1)→(1,3)→(2,3)→(3,3)
(1,1)→(1,3)→(3,3)
(1,1)→(2,1)→(3,1)→(3,2)→(3,3)
(1,1)→(2,1)→(3,1)→(3,3)
(1,1)→(2,1)→(3,2)→(3,3)
(1,1)→(3,1)→(3,2)→(3,3)
(1,1)→(3,1)→(3,3)
Sample Input 2
4 4
...#
....
..#.
....
Sample Output 2
84
From (1,1), the queen can move to (1,2), (1,3), (2,1), (2,2), (3,1), or (4,1).
One possible path to (4,4) is (1,1)→(3,1)→(3,2)→(4,3)→(4,4).
Sample Input 3
8 10
..........
..........
..........
..........
..........
..........
..........
..........
Sample Output 3
13701937
思路解析
这题就是一个简单的DP,为啥说简单呢,因为这个DP就是最初学习DP的那个统计方案数的DP,上下左右移动,最后一个有多少种方案。
为啥这个题不简单呢,因为这个题的移动方案不是一次一格了,而统计的是三个方向路线上的所有。
思路很简单,暴力跑先前的方案,会重复多跑好多次,所以加个前缀和就OK了。
水平方向,竖直方向可以直接根据坐标进行判断,而斜着的方向需要做一下特殊处理,这里我用的是map,方案很多,方便就行。
//#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const ll less_inf = 0x3f3f3f3f;
const char char_inf = 127;
#pragma GCC optimize(2)
#define PI 3.141592653589793
#define EPS 1.0e-8
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
inline ll read() {
ll c = getchar(), Nig = 1, x = 0;
while (!isdigit(c) && c != '-')c = getchar();
if (c == '-')Nig = -1, c = getchar();
while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
return Nig * x;
}
inline void out(ll a) {
if (a < 0)putchar('-'), a = -a;
if (a > 9)out(a / 10);
putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
ll res = 1;
while (n > 0) {
if (n & 1)res = (res * x) % mod;
x = (x * x) % mod;
n >>= 1;
}
return res;
}
const ll N = 1e9 + 7;
#define Floyd for(int k = 1; k <= n; k++)for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)
#define read read()
char save[2005][2005];
ll dp[2005][2005];
ll vertical[2005];
ll cross[2005];
map<int, map<int, ll>>oblique;
int main()
{
ll mod = 1e9 + 7;
ll n = read, m = read;
for (int i = 1; i <= n; i++)
scanf("%s", save[i] + 1);
for (int j = 0; j <= m; j++)
save[0][j] = save[n + 1][j] = '#';
for (int i = 0; i <= n + 1; i++)
save[i][0] = save[i][m + 1] = '#';
dp[1][1] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (save[i][j] == '.')
{
dp[i][j] += cross[i];
dp[i][j] += vertical[j];
int nx = i, ny = j;
int temp = min(nx, ny);
nx -= temp;
ny -= temp;
dp[i][j] += oblique[nx][ny];
dp[i][j] %= mod;
cross[i] = (dp[i][j] + cross[i]) % mod;
vertical[j] = (dp[i][j] + vertical[j]) % mod;
oblique[nx][ny] = (dp[i][j] + oblique[nx][ny]) % mod;
}
else
{
cross[i] = 0;
vertical[j] = 0;
int nx = i, ny = j;
int temp = min(nx, ny);
nx -= temp;
ny -= temp;
oblique[nx][ny] = 0;
}
out(dp[n][m]);
puts("");
return 0;
}
By-轮月