Loading

Codeforces Round #662 (Div. 2) D. Rarity and New Dress 预处理的DP

 

 题意:问给定的矩阵中形如绿色的块的个数。

红色是不合法的。第一个红没有全是同样的字母。第二个红越界。第三个红不是斜的45度

 

对矩形预处理。l[i][j]表示(i , j) 最大向上延伸的长度,其他同理。

mid[i][j] 表示这个点左右延申的最大长度。

用u[i][j]表示向上形成三角形的个数。 转移方程 u[i][j] = min(u[i - 1][j] + 1, mid[i][j] )

最后只需对每个点取min(u,d)即可。

#pragma warning(disable:4996)
 
#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include <assert.h>
#define pb push_back
#define INF 0x3F3F3F3F
#define inf 1000000007
#define moD 1000000003
#define pii pair<int,int>
#define eps 1e-6
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
typedef  long long ll;
typedef unsigned long long ull;
const ll MOD = 1000000007;
const int maxn = 2005;
const double Inf = 10000.0;
const double PI = acos(-1.0);
using namespace std;
 
ll mul(ll a, ll b, ll m) {
    ll res = 0;
    while (b) {
        if (b & 1) res = (res + a) % m;
        a = (a + a) % m;
        b >>= 1;
    }
    return res % m;
}
 
ll quickPower(ll a, ll b, ll m) {
    ll base = a;
    ll ans = 1ll;
    while (b) {
        if (b & 1) ans = mul(ans, base, m);
        base = mul(base, base, m);
        b >>= 1;
    }
    return ans;
}
 
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}
 
ll Lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}
 
int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
 
ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
 
ull readull() {
    ull x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
 
void Put(ll x) {
    if (x < 0) putchar('-'), x *= -1;
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}
 
char s[maxn][maxn];
int l[maxn][maxn],r[maxn][maxn];
int mid[maxn][maxn];
int n,m;
int u[maxn][maxn],d[maxn][maxn];
 
int main(){
    n = readint(), m = readint();
    for(int i = 1; i <= n;i++) scanf("%s",s[i] + 1);
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++) if(s[i][j] == s[i][j - 1]) l[i][j] = l[i][j - 1] + 1; else l[i][j] = 1;
        for(int j = m; j >= 1;j--) {
        if(s[i][j] == s[i][j + 1]) r[i][j] = r[i][j + 1] + 1; else r[i][j] = 1;
        mid[i][j] = min(l[i][j],r[i][j]);
        }
    }
    for(int i = 1;i <= m;i++){
        for(int j = 1;j <= n;j++){
            if(s[j][i] == s[j -1][i]) u[j][i] = min(mid[j][i],u[j - 1][i] + 1); else u[j][i] = 1;
        }
        for(int j = n;j >= 1;j--) {
            if(s[j][i] == s[j + 1][i]) d[j][i] = min(mid[j][i],d[j + 1][i] + 1);
            else d[j][i] = 1;
        }
    }
    int ans = 0;
    for(int i = 1; i <= n;i++) for(int j = 1;j  <= m;j++) ans += min(u[i][j],d[i][j]);
    Put(ans);
}
 
 

 

posted @ 2020-08-08 20:28  MQFLLY  阅读(237)  评论(0编辑  收藏  举报