Description
给出一个H的行和W列的网格。第i行第j列的状态是由一个字母的A[i][j]表示,如下:
“.” 此格为空。
“o” 此格包含一个机器人。
“E” 此格包含一个出口,保证出口在整个网格中有且只有一个
每次可以选择上,下,左,右之一的方向,将所有剩余的机器人向这个方向移动一个格子,如果一个机器人被移出了网格,那么这个机器人会爆炸,并立即消失。如果一个机器人移动到出口所在的格子,机器人将获救,并消失,最多有多少机器人获救。
Input
第一行两个整数n,m
接下来一个n*m的字符矩阵,共n行,每行m个字符,每个字符之间无空格,字符意义如题所示。
Output
输出一个整数,即最大的获救的机器人的数量
Sample Input
【样例输入1】
3 3
o.o
.Eo
ooo
【样例输入2】
3 4
o…
o…
oooE
Sample Output
【样例输出1】
3
【样例输出2】
5
Data Constraint
对于20%的数据,n*m<=9
对于另外40%的数据,出口在网格图的最左上角,即第1行第1列。
对于100%的数据,n,m<=100
Hint
移动序列为左,上,右时,第2行第3个与第3行第2,3个机器人获救,其他机器人爆炸
解法
dp。
我们可以知道,如果我们牺牲掉最左边一列,那么出口右边的一列就能够加入答案。那么四个方向上的是同理。
设f[l][r][u][d]表示左边牺牲l列,右边r列,上面u行,下面d行能够获得的最大数量。转移明显了。
发现空间会炸,可以开滚动。
懒得人直接用小一点的数据类型
然而我因为数组没开够调了两天QwQ.
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(short i=a;i<=b;i++)
using namespace std;
const short maxn=105;
short f[maxn][maxn][maxn][maxn],H[maxn][maxn],L[maxn][maxn],map[maxn][maxn],n,m,x,y,ans;
char ch;
short max(short x,short y)
{
if (x>y) return x; else return y;
}
short min(short x,short y)
{
if (x<y) return y; else return x;
}
int main()
{
// freopen("T.in","r",stdin);
// freopen("T.out","w",stdout);
cin>>n>>m;
ch=getchar();
fo(i,1,n){
while(ch!='o'&&ch!='.'&&ch!='E') ch=getchar();
short j=1;
while (ch=='o'||ch=='.'||ch=='E'){
if (ch=='o') map[i][j]=1;
else if (ch=='E') x=i,y=j;
ch=getchar();
++j;
}
}
fo(i,1,n)
fo(j,1,m) H[i][j]=H[i][j-1]+map[i][j];
fo(i,1,m)
fo(j,1,n) L[i][j]=L[i][j-1]+map[j][i];
memset(f,128,sizeof(f));
f[0][0][0][0]=0;
fo(l,0,m-y)
fo(r,0,y-1)
fo(u,0,n-x)
fo(d,0,x-1)
if (f[l][r][u][d]>=0)
{
if (y+l+1<=m-r){
f[l+1][r][u][d]=max(f[l+1][r][u][d],
f[l][r][u][d]+L[y+l+1][min(x+u,n-d)]-L[y+l+1][max(x-d-1,u)]);
ans=max(ans,f[l+1][r][u][d]);
}
if (y-r-1>l){
f[l][r+1][u][d]=max(f[l][r+1][u][d],
f[l][r][u][d]+L[y-r-1][min(x+u,n-d)]-L[y-r-1][max(x-d-1,u)]);
ans=max(ans,f[l][r+1][u][d]);
}
if (x+u+1<=n-d){
f[l][r][u+1][d]=max(f[l][r][u+1][d],
f[l][r][u][d]+H[x+u+1][min(y+l,m-r)]-H[x+u+1][max(y-r-1,l)]);
ans=max(ans,f[l][r][u+1][d]);
}
if (x-d-1>u){
f[l][r][u][d+1]=max(f[l][r][u][d+1],
f[l][r][u][d]+H[x-d-1][min(y+l,m-r)]-H[x-d-1][max(y-r-1,l)]);
ans=max(ans,f[l][r][u][d+1]);
}
}
printf("%d",ans);
}