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;
}

原文地址:https://www.cnblogs.com/xiaopangpangdehome/p/14152035.html