jzoj3692. 【SRM 611】ElephantDrinking

题目描述

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

猜你喜欢

转载自blog.csdn.net/gmh77/article/details/99193495