题意:
给你一张n*n的图,每个位置有’#‘和’.‘两种元素中的一种,你每次可以选择一个矩形使得其中的所有元素变成’.’,并且花费是长和宽的最大值,你可以做无数次这种操作,问你将所有元素变成’.'的最小花费是多少。
题解:
暴力枚举上下和左右两种区间转移即可,算起来是 ,但是常数比较小所以能过。
#include<bits/stdc++.h>
using namespace std;
const int N=55;
int dp[N][N][N][N];
char mp[N][N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=n;j++)
dp[i][i][j][j]=mp[i][j]=='#'?1:0;
}
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
for(int k=1;k<=n;k++){
for(int l=k;l<=n;l++){
if(j==i&&k==l)continue;
dp[i][j][k][l]=max(j-i+1,l-k+1);
}
}
}
}
for(int l1=1;l1<=n;l1++){
for(int l2=1;l2<=n;l2++){
for(int i=1;i+l1-1<=n;i++){
for(int j=1;j+l2-1<=n;j++){
for(int k=i;k<i+l1-1;k++){
dp[i][i+l1-1][j][j+l2-1]=min(dp[i][i+l1-1][j][j+l2-1],dp[i][k][j][j+l2-1]+dp[k+1][i+l1-1][j][j+l2-1]);
}
for(int k=j;k<j+l2-1;k++){
dp[i][i+l1-1][j][j+l2-1]=min(dp[i][i+l1-1][j][j+l2-1],dp[i][i+l1-1][j][k]+dp[i][i+l1-1][k+1][j+l2-1]);
}
}
}
}
}
printf("%d\n",dp[1][n][1][n]);
return 0;
}