记录编号 126335 评测结果 AAAAAAAAAA
题目名称 [NOIP 2010]引水入城 最终得分 100
用户昵称 GravatarHzoi Angel 是否通过 通过
代码语言 C++ 运行时间 0.752 s
提交时间 2014-10-12 07:23:51 内存使用 1.58 MiB
显示代码纯文本
/*
	author	:hzoi_ztx
	title	:cogs 521 [NOIP2010] 引水入城
	ALG		:贪心。。dp 
	comment	:f[i]表示以线段i为结尾的连接到1的最少线段数
			 f[i] = min(f[j]+1) ;
			 (line[j].s<line[i].s && line[j].t>=line[i].s-1)
			 f[0] = 0 ; line[0].s = 0 ; line[0].t = 0 ;
*/

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>

#define  maxn	520
#define  maxm	520
#define  info	0x3f3f3f3f

int ret , ch ;
inline int qread() {
	ret = 0 ; while (!isdigit(ch=getchar())) ;
	while (ret=ret*10+ch-'0',isdigit(ch=getchar())) ;
	return ret ;
} 

int dx[4] = {-1 , 1 , 0 , 0 } ;
const int dy[4] = {0 , 0 , -1 , 1 } ;

struct seg{
	int s , t ;
	seg() { s = t = info ; }
	void update(int p) {
		if (t==info || p>t) t = p ;
		if (s==info || p<s) s = p ;
	}
	bool operator < (const seg a) const { 
		return s < a.s ;
	}
} line[maxm] ;

bool visit[maxn][maxn] ;
bool flag[maxn] = {false} ;

int n , m , ans = 0 ;
int h[maxn][maxm] ;
int f[maxm] ;

inline void fill(int x,int y,int p) {
	if (x<1 || y<1 || x>n || y>m) return ;
	if (x == n) {
		flag[y] = true ; line[p].update(y) ;
	}
	visit[x][y] = true ;
	for (int i = 0 ; i < 4 ; i ++ )
		if (!visit[x+dx[i]][y+dy[i]] && h[x][y]>h[x+dx[i]][y+dy[i]])
			fill(x+dx[i] , y+dy[i] , p) ;
	//不信邪了 = = 
	/*
	if(!visit[x+1][y] && h[x+1][y] < h[x][y]) fill(x+1, y, p);
    if(!visit[x][y+1] && h[x][y+1] < h[x][y]) fill(x, y+1, p);
    if(!visit[x-1][y] && h[x-1][y] < h[x][y]) fill(x-1, y, p);
    if(!visit[x][y-1] && h[x][y-1] < h[x][y]) fill(x, y-1, p);
    ////这么不科学的事!!!!!!!!!! 
	*/
}

inline void dp() {
	putchar('1') ;
	std::sort(line+1 , line+m+1) ;
	memset(f , 0x3f , sizeof (f)) ;
	ans = info ;
	int i , j ;
	f[0] = 0 ; line[0].s = 0 ; line[0].t = 0 ;
	for (i = 0 ; i <= m ; i ++ ) {
		if (line[i].s == info) break ; //可能一些蓄水厂不能将水引向另一岸 
		for (j = i+1 ; j <= m ; j ++ ) {
			if (line[j].s > line[i].t+1) break ;
			if (f[i]+1 < f[j]) f[j] = f[i]+1 ;
		}
		if (line[i].t==m && f[i]<ans) ans = f[i] ;
	}
}

int main() {
	#define  READ
	#ifdef   READ
		freopen("flow.in" ,"r",stdin ) ;
		freopen("flow.out","w",stdout) ;
	#endif
	n = qread() ; m = qread() ;
	int i , j ;
	for (i = 1 ; i <= n ; i ++ )
		for (j = 1 ; j <= m ; j ++ )
			h[i][j] = qread() ; 
	for (j = 1 ; j <= m ; j ++ ) {
		memset(visit , 0 , sizeof (visit)) ;
		fill(1 , j , j) ;
	}
	for (j = 1 ; j <= m ; j ++ )
		if (!flag[j])
			ans ++ ;
	if (ans) putchar('0') ;
	else dp() ;
	printf("\n%d\n", ans ) ;
	return 0 ;
}