记录编号 | 126335 | 评测结果 | AAAAAAAAAA | ||
---|---|---|---|---|---|
题目名称 | [NOIP 2010]引水入城 | 最终得分 | 100 | ||
用户昵称 | 是否通过 | 通过 | |||
代码语言 | 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 ; }