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