[CF1393D] Rarity and New Dress - dp
阿新 • • 發佈:2020-11-03
Description
給定一個 \(n \times m\) 的網格,每個格子有一個顏色,問有多少個同色菱形。\(n,m \le 2000\)
Solution
類似“最大正方形”的套路,設 \(f[i][j]\) 表示以 \((i,j)\) 點為下頂點的菱形的最大邊長,轉移時考慮 \((i,j),(i-1,j),(i-2,j),(i-1,j-1),(i-1,j+1)\) 這五個點是否相等,如果相等則從 \(f[i-1][j],f[i-2][j],f[i-1][j-1],f[i-1][j+1]\) 中取最小值轉移過來即可。
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 2005; char a[N][N]; int f[N][N],n,m; signed main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]+1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(i>1 && j>1) { if(a[i-1][j-1]==a[i-1][j] && a[i-1][j+1]==a[i-1][j] && a[i-2][j]==a[i-1][j] && a[i][j]==a[i-1][j]) { f[i][j]=max(f[i][j],min(min(f[i-1][j-1],f[i-1][j+1]),min(f[i-1][j],f[i-2][j]))+1); } } int ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans+=f[i][j]; cout<<ans<<endl; return 0; }