不要被假象迷惑,其实这是一道区间dp,如果过多的考虑怎么放长方形就容易进入误区。
我们考虑一个dp状态表示f[][][][],将一个长方形中所有的点变成”."的最小代价,之后枚举行列进行区间dp,这其中其实已经做好了划分长方形的工作。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=5e5+10; const int M=2e6+10; const int inf=0x3f3f3f3f; int n; int f[55][55][55][55]; string s[N]; int main(){ ios::sync_with_stdio(false); cin>>n; int i; for(i=1;i<=n;i++){ cin>>s[i]; s[i]=" "+s[i]; } for(int lenx=1;lenx<=n;lenx++){ for(int leny=1;leny<=n;leny++){ for(int x=1;x+lenx-1<=n;x++){ for(int y=1;y+leny-1<=n;y++){ int x1=x+lenx-1; int y1=y+leny-1; if(lenx==1&&leny==1){ if(s[x][y]=='#') f[x][y][x][y]=1; continue; } f[x][y][x1][y1]=max(lenx,leny); for(int k=x;k<x1;k++) f[x][y][x1][y1]=min(f[x][y][x1][y1],f[x][y][k][y1]+f[k+1][y][x1][y1]); for(int k=y;k<y1;k++) f[x][y][x1][y1]=min(f[x][y][x1][y1],f[x][y][x1][k]+f[x][k+1][x1][y1]); } } } } cout<<f[1][1][n][n]<<endl; }