[ABC233G] Strongest Takahashi
Problem Statement
There is a grid, with blocks on some squares.
The grid is described by strings , as follows.
- If the -th character of is
#
, there is a block on the square at the -th row from the top and -th column from the left. - If the -th character of is
.
, there is not a block on the square at the -th row from the top and -th column from the left.
Takahashi can do the operation below zero or more times.
- First, choose an integer between and (inclusive), and a subsquare within the grid.
- Then, consume stamina points to destroy all blocks within the subsquare.
Find the minimum number of stamina points needed to destroy all the blocks.
Constraints
- is an integer.
- consists of
#
and.
.
Input
Input is given from Standard Input in the following format:
$N$ $S_1$ $S_2$ $\vdots$ $S_N$
Output
Print the answer as an integer.
Sample Input 1
5 ##... .##.. #.#.. ..... ....#
Sample Output 1
4
By choosing the subsquares below, Takahashi will consume stamina points, which is optimal.
- The subsquare whose top-left square is at the -st row from the top and -st column from the left.
- The subsquare whose top-left square is at the -th row from the top and -th column from the left.
Sample Input 2
3 ... ... ...
Sample Output 2
0
There may be no block on the grid.
Sample Input 3
21 ..................... ..................... ...#.#............... ....#.............#.. ...#.#...........#.#. ..................#.. ..................... ..................... ..................... ..........#.....#.... ......#..###......... ........#####..#..... .......#######....... .....#..#####........ .......#######....... ......#########...... .......#######..#.... ......#########...... ..#..###########..... .........###......... .........###.........
Sample Output 3
19
50的数据范围,基本上高次dp或者折半搜索的。这题不太像折半搜索,那就试一下高维dp。
定义 为解决以 为左上角,以 为右下角矩形 所需的最小代价.
首先肯定有一种 的方案,那就是把他填满。
有一个引理,在我们填的矩阵中,一定不可能接壤,不然的话就可以选一个更大的矩阵,在代价一样的情况下框住的面积更大了。
所以如果不是全选的话,一定可以沿着某一行或者某一列把大矩阵割成两个矩阵解决。枚举对应的这一行或一列,递归下去就行了
这个dp的顺序应该按照区间dp的顺序。
#include<bits/stdc++.h>
using namespace std;
const int N=55;
int n,dp[N][N][N][N],c1[N][N],c2[N][N],r1,r2;
char s[N][N];
void tomax(int&a,int b)
{
a=min(a,b);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
c1[i][j]=c1[i][j-1]+(s[i][j]=='#');
c2[i][j]=c2[i-1][j]+(s[i][j]=='#');
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int l1=1;l1+i-1<=n;l1++)
{
for(int l2=1;l2+j-1<=n;l2++)
{
r1=l1+i-1,r2=l2+j-1;
dp[l1][l2][r1][r2]=max(i,j);
for(int k=l1;k<=r1;k++)
if(c1[k][r2]==c1[k][l2-1])
tomax(dp[l1][l2][r1][r2],dp[l1][l2][k-1][r2]+dp[k+1][l2][r1][r2]);
for(int k=l2;k<=r2;k++)
if(c2[l1-1][k]==c2[r1][k])
tomax(dp[l1][l2][r1][r2],dp[l1][l2][r1][k-1]+dp[l1][k+1][r1][r2]);
// printf("%d %d %d %d %d\n",l1,l2,r1,r2,dp[l1][l2][r1][r2]);
}
}
}
}
printf("%d",dp[1][1][n][n]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】