題目大意
給定一個矩形網格的長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;
}
}