题目描述
Description
这里有一个n*n 的平原,其中一些格子有泉水。你会得到一个string 字符串组,作为地图被用于描述平原。string 有n 个字符串,每个字符串长度为n,每个字符为0 到9 的数字。数字0 代表这个格子没有水;数字1 到9 代表泉水,并且数字为泉眼出水的速率。例如,数字5 表示一个每单位时间产生5 单位水的泉水。
平原周围有4n 头大象:绕着平原的边缘,每一格边都有一头大象,如下图所示。这些大象使用长鼻子喝水,但是它们的鼻子只能笔直地伸向自己面对的方向。因此,例如在平原的左边界的大象,它们只能往正右方伸鼻子。神奇的是,它们的鼻子很长以至于能够碰到平原对面的边缘。大象可以喝任意速率出水的泉水,不过没有被鼻子照顾的泉水都会被泥土吸收。
在这题里还有两个附加的限制条件:大象的鼻子不能相交。对于每个泉水,最多只能被一头大象占领。
例如,图(a) 演示了一个合法的方案。有泉水的格子是蓝色的,大象是绿色的,它们的鼻子是红色的。这幅图中有四头大象在喝水。图(b) 和© 都是不合法的方案,它们两个里都有大象鼻子相交的情况。
你的任务是计算大象们每单位时间最多能喝多少的水。
Input
多组数据,读入至文件结束。
每组数据第一行为一个整数n(如题目描述),接下来n 行给出字符串组。这n 行中每行为一个长度等于n 的字符串,字符串的字符为数字0 到9。
Output
对于每组数据输出单独一行一个整数,即那组数据中大象们最多能喝多少单位水。
Sample Input
5
00000
00110
01000
00100
00000
3
111
191
111
4
1010
0011
1100
1111
4
0011
1110
0111
0101
5
11100
00100
11111
00100
10111
6
023771
509514
675579
367472
575198
115281
Sample Output
4
16
10
10
13
112
【样例解释】
• 第一组数据:这是题目描述中图片展示的平原。所有泉眼出水速率都是1。
如图(a) 所示,可以让四头大象同时喝水,并且我们只有四个格子有水,因此这明显是最优解。
• 第二组数据:在最优解中,会有7 头大象从出水速率为1 的泉里喝水,还有一头大象从出水速率为9 的中心泉里吸水喝。这些个大象每单位时间消耗的泉水为7 * 1 + 1 * 9 = 16 单位。
Data Constraint
对于30% 的数据,n,m <= 5,数据组数<=7
对于100% 的数据,2 <= n,m <= 50,数据组数<= 17
题解
码农题(3/3)
众所周知,大象是绿色的
考虑dp
分四种情况
①
箭头是大象的方向
②
把①转过来
③
④
把③反过来
分别处理从四个角开始的最优解,处理每行/每列的选法和选择某行/列两侧的最优方案
然后随便搞搞
可以发现这几种情况包含了所有的解法
code
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;
int map[51][51];
int mx[4][52][52];//→←↓↑
int f[4][52][52]; //↘↖↙↗
int b[2][52]; //→↓
int c[4][52]; //→←↓↑
int n,i,j,k,l,s,ans;
char ch;
int Get()
{
ch=getchar();
while (ch<'0' || ch>'9')
ch=getchar();
return ch-'0';
}
int main()
{
// freopen("S8_10_3.in","r",stdin);
while (~scanf("%d",&n))
{
ans=0;
memset(mx,0,sizeof(mx));
memset(f,0,sizeof(f));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
fo(i,1,n)
{
fo(j,1,n)
map[i][j]=Get();
}
fo(i,1,n)
{
fo(j,1,n)
mx[0][i][j]=max(mx[0][i][j-1],map[i][j]);
}
fo(i,1,n)
{
fd(j,n,1)
mx[1][i][j]=max(mx[1][i][j+1],map[i][j]);
}
fo(j,1,n)
{
fo(i,1,n)
mx[2][i][j]=max(mx[2][i-1][j],map[i][j]);
}
fo(j,1,n)
{
fd(i,n,1)
mx[3][i][j]=max(mx[3][i+1][j],map[i][j]);
}
fo(i,1,n)
{
fo(j,1,n)
f[0][i][j]=max(f[0][i-1][j]+mx[0][i][j],f[0][i][j-1]+mx[2][i][j]);
}
fd(i,n,1)
{
fd(j,n,1)
f[1][i][j]=max(f[1][i+1][j]+mx[1][i][j],f[1][i][j+1]+mx[3][i][j]);
}
fo(i,1,n)
{
fd(j,n,1)
f[2][i][j]=max(f[2][i-1][j]+mx[1][i][j],f[2][i][j+1]+mx[2][i][j]);
}
fd(i,n,1)
{
fo(j,1,n)
f[3][i][j]=max(f[3][i+1][j]+mx[0][i][j],f[3][i][j-1]+mx[3][i][j]);
}
fo(i,1,n)
{
fo(j,0,n)
b[0][i]=max(b[0][i],mx[0][i][j]+mx[1][i][j+1]);
}
fo(j,1,n)
{
fo(i,0,n)
b[1][j]=max(b[1][j],mx[2][i][j]+mx[3][i+1][j]);
}
fo(j,1,n)
{
fo(i,0,n)
c[0][j]=max(c[0][j],f[0][i][j]+f[3][i+1][j]);
}
fd(j,n,1)
{
fo(i,0,n)
c[1][j]=max(c[1][j],f[2][i][j]+f[1][i+1][j]);
}
fo(i,1,n)
{
fo(j,0,n)
c[2][i]=max(c[2][i],f[0][i][j]+f[2][i][j+1]);
}
fd(i,n,1)
{
fo(j,0,n)
c[3][i]=max(c[3][i],f[3][i][j]+f[1][i][j+1]);
}
fo(i,0,n) //lie
{
s=0;
fo(j,i+1,n+1)
{
ans=max(ans,c[0][i]+s+c[1][j]);
s+=b[1][j];
}
}
fo(i,0,n) //hang
{
s=0;
fo(j,i+1,n+1)
{
ans=max(ans,c[2][i]+s+c[3][j]);
s+=b[0][j];
}
}
fo(i,0,n)
{
fo(j,0,n)
{
fo(k,i+1,n+1)
{
fo(l,j+1,n+1)
ans=max(ans,max(f[0][i][l-1]+f[1][k][j+1]+f[2][k-1][l]+f[3][i+1][j],f[0][k-1][j]+f[1][i+1][l]+f[2][i][j+1]+f[3][k][l-1]));
}
}
}
printf("%d\n",ans);
}
}