Codeforces 1198 D Rectangle Painting 1 —— 二维区间dp

This way

题意:

给你一张n*n的图,每个位置有’#‘和’.‘两种元素中的一种,你每次可以选择一个矩形使得其中的所有元素变成’.’,并且花费是长和宽的最大值,你可以做无数次这种操作,问你将所有元素变成’.'的最小花费是多少。

题解:

暴力枚举上下和左右两种区间转移即可,算起来是 O ( n 5 ) O(n^5) ,但是常数比较小所以能过。

#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;
}

发布了554 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104362473