4 条题解
-
12
【挑战题】JUMP THE BOARD! P1232
题意回顾
一个 n×n 的游戏板是由整数填充的,每格一个非负整数。目标是从左上角以任何合法路径跳到右下角。任何一格中的整数表示跳离该位置的步长。如果步长将推进越出游戏板,那么在那个特定的方向上的跳步是禁止的。所有的跳步必须是向右或向下。请注意,0 是一个死胡同,它阻止任何进一步的进展。 如图 1 中所示的 4×4 板,实圆标识起始位置,虚线圆标识目标位置。图 2 展示了从起点位置到目标位置的三条合法路径,每个路径中都删除了不相关的数字。 你的任务是编写一个程序来确定从左上角到右下角的合法路径的数量。
输入格式
第一行包含一个正整数 n,表示该板的行列数。接下来 n 行数据。每行包含 n 个整数,每个整数的范围是 0⋯9。
输出格式
唯一的一行包含一个整数,即从左上角到右下角的合法路径数对1e9+7取模之后结果。
思路
主动转移
完整代码
#include <bits/stdc++.h> using namespace std; const int mod=1e9+7; const int N=105; int n; long long a[N][N],f[N][N]; int main(){ cin>>n; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) cin>>a[i][j];//输入 f[1][1]=1;//初始化 for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ if (!a[i][j]) continue;//当a[i][j]==0的时候,就直接跳出 if (i+a[i][j]<=n){//不会出界的话就转移 f[i+a[i][j]][j]=(f[i+a[i][j]][j]+f[i][j])%mod; } if (j+a[i][j]<=n){//同理 f[i][j+a[i][j]]=(f[i][j+a[i][j]]+f[i][j])%mod; } } } cout<<f[n][n]; return 0; }
点赞点赞
-
1
PY:
dp = [] g = [] for i in range(0, 110): dp.append([]) g.append([]) for j in range(0, 110): dp[i].append(0) n = int(input()) for i in range(1, n + 1): g[i] = input().split() g[i].append(int(g[i][n - 1])) for j in range(n - 1, 0, -1): g[i][j] = int(g[i][j - 1]) dp[1][1] = 1 g[n][n] = 1 for i in range(1, n + 1): for j in range(1, n + 1): if(i + g[i][j] <= n): dp[i + g[i][j]][j] += dp[i][j] if(j + g[i][j] <= n): dp[i][j+g[i][j]] += dp[i][j] print(dp[n][n])
-
0
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int N=105; int n,a[N][N]; struct Bigint { int x[105]; Bigint() { memset(x, 0, sizeof(x)); x[0] = 1; } void print() { for (int i = x[0]; i >= 1; i--) { cout << x[i]; } cout << endl; } Bigint operator+(const Bigint &B) const { Bigint c; c.x[0] = max(x[0], B.x[0]); for (int i = 1; i <= c.x[0]; i++) c.x[i] = x[i] + B.x[i]; for (int i = 1; i <= c.x[0]; i++) { c.x[i + 1] += c.x[i] / 10; c.x[i] %= 10; } if (c.x[c.x[0] + 1] > 0) c.x[0]++; return c; } }f[N][N]; int main() { cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; f[1][1].x[1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(!a[i][j]) continue; if(i+a[i][j]<=n) f[i+a[i][j]][j]=f[i+a[i][j]][j]+f[i][j]; if(j+a[i][j]<=n) f[i][j+a[i][j]]=f[i][j+a[i][j]]+f[i][j]; } f[n][n].print(); return 0; }
-
-1
思路
这一题的难点时需要主动转移。 $\\$(1)状态定义:$f[i][j]$表示到达$a[i][j]$的方案数 $\\$(2)初始状态:$f[1][1]$设为1 $\\$(3)状态转移:使用主动转移,如果$a[i][j]$不是0,且转移后不越界,那么$f[i][j]$可以转移给$f[i+a[i][j]][j]$和$f[i][j+a[i][j]]$代码
#include<bits/stdc++.h> using namespace std; const int N=103; const int mod=1e9+7; int n; long long a[N][N],f[N][N];
int main() { cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; f[1][1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(!a[i][j]) continue; if(i+a[i][j]<=n) f[i+a[i][j]][j]=(f[i+a[i][j]][j]+f[i][j])%mod; if(j+a[i][j]<=n) f[i][j+a[i][j]]=(f[i][j+a[i][j]]+f[i][j])%mod; } cout<<f[n][n]; }
- 1
信息
- ID
- 520
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- (无)
- 递交数
- 200
- 已通过
- 140
- 上传者