題:https://codeforces.com/contest/1393/problem/D
題意:給出n*n的字符矩陣,問矩陣中有多少個相同字符的“斜正方形”。
分析:對於每一個位置我們設dp[i][j]為位置[i][j]向上能最多”延申“的”斜正方形邊長“,那么總的答案就是所有位置的dp值之和。
轉移分為當前位置[i][j]與上面四個位置([i-1][j]、[i-1][j-1]、[i-1][j+1]、[i-2][j])能否形成“斜正方形”:
若能,則取min(dp[i-1][j-1]、dp[i-1][j+1]、dp[i-2][j])+1,這里可以簡單畫個圖理解一下當前[i][j]高度的“延申”只是依賴於這三個位置的dp值,
若不能則dp[i][j]=1;

#include <bits/stdc++.h> using namespace std; const int M=2e3+10; typedef long long ll; char a[M][M]; int f[M][M],n,m,i,j; ll ans=0; int main(){ scanf("%d%d",&n,&m); for(i=2;i<=n+1;i++) scanf("%s",a[i]+1); for(i=2;i<=n+1;i++) for (j=1;j<=m;j++){ if ((a[i][j]!=a[i-1][j]) || (a[i][j]!=a[i-1][j-1]) || (a[i][j]!=a[i-1][j+1]) || (a[i][j]!=a[i-2][j])) f[i][j]=1; else f[i][j]=1+min(min(f[i-1][j-1],f[i-1][j+1]),f[i-2][j]); ans+=1LL*f[i][j]; } printf("%I64d\n",ans); return 0; }