1. 程式人生 > 實用技巧 >Codeforces Round #689 (Div. 2, based on Zed Code Competition)/1461B Find the Spruce

Codeforces Round #689 (Div. 2, based on Zed Code Competition)/1461B Find the Spruce

題目連結:https://codeforces.com/contest/1461/problem/B

題目大意:給定一個矩陣,求其中樓梯狀等腰三角形(叫它等腰樓梯吧0v0)的個數

題目思路:觀察下圖,發現最高點如果能構成更高階的等腰樓梯,那麼它的(i+1,j+1)(i+1,j)(i+1,j-1)三點必是低一級的等腰樓梯,順著這樣的想法,從下往上dp,得出狀態轉移方程dp[i][j] = min(dp[i + 1][j - 1], min(dp[i + 1][j], dp[i + 1][j + 1])) + 1

AC程式碼:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <stack>
#include <deque>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int N = 610, M = 3 * N;
const int base = 1e9;
const int P = 131;
int n, m, t, k;
char g[N][N];
int dp[N][N];
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        memset(dp, 0, sizeof(dp));
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; ++i)
            scanf("%s", g[i] + 1);
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                if (g[i][j] == '*')
                    dp[i][j] = 1;
        int ans = 0;
        for (int i = n; i >= 1; --i)
            for (int j = 1; j <= m; ++j)
                if (dp[i][j])
                {
                    dp[i][j] = min(dp[i + 1][j - 1], min(dp[i + 1][j], dp[i + 1][j + 1])) + 1;
                    ans += dp[i][j];
                }
        printf("%d\n", ans);
    }
    return 0;
}