题目大意
给定一个矩形网格的长m和高n,其中m和n都是unsigned int32类型,一格代表一个单位,就是一步,求从左下角到右上角有多少种走法,每步只能向上或者向右走
解题思路
首先题目上说了答案不会超过int型变量,我们可以简单算一下,如果是的图,大概在100000左右就会超出int变量的范围,如果是的图,那么的范围会更小,当时,返回,时返回,然后我们讨论的场景
首先,拿出我们的dp公式,
for (int i = 1; i <= n; i++)dp[i][1] = 1;
for (int i = 1; i <= m; i++)dp[1][i] = 1;
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
此时一个维度最小开100000,那么很容易MLE,可以观察到这里可以使用滚动数组进行一步优化,直接就避免了MLE的情况
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
dp[i % 2][j] = dp[(i % 2) ^ 1][j] + dp[i % 2][j - 1];
很多人会遇到TLE的问题,这是因为一个维度=1时,另一个维度可以非常大,因此我们讲一维=1的情况单独进行讨论就避免了TLE。
完整代码
//1724K 32MS
#define inf 0x3f3f3f3f
#define ll long long
#define vec vector<int>
#define P pair<int,int>
#define MAX 100000
ll n, m, dp[2][MAX];
string s, t;
int main() {
while (scanf("%lld %lld", &m, &n) && n + m) {
memset(dp, 0, sizeof(dp));
if (m > n)swap(n, m);
if (m == 0) { cout << 1 << endl; continue; }
if (m == 1) { cout << n + 1 << endl; continue; }
n++, m++;
for (int i = 1; i <= m; i++)dp[1][i] = 1;
dp[0][1] = dp[1][0] = 1;
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
dp[i % 2][j] = dp[(i % 2) ^ 1][j] + dp[i % 2][j - 1];
cout << dp[n % 2][m] << endl;
}
}