引水入城(codevs 1066)
2016-07-03 16:45
369 查看
题目描述 Description
View Code
/* 分析:这道题只得了50分,然而看题解,大体思路是相同的,DP写的太烂了,n^4, 其实本来就是冲着70分去的,结果题目要求如果建不成,输出有多少建不成,我输出的有多少能建成,所以又多WA了2个点 思路:<1>对于第一行的每个点我们再通过搜索求出其所能到达最后一行所有的点,可以证明这些点一定是连续的。假设这些点中间如果有断开的话,设中间不能走到的那个点为x,那么x必大于左边的高度,必大于右边的高度,必大于上一行的高度,则x这个点无法到达,即此问无解,与之前我们确认过有解相矛盾,假设不成立,故命题成立。 <2> 这样我们算出第一行每个点所对应的最后一行的区间,记下左边界和右边界,然后就是典型的线段覆盖动规了。 */ #include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<algorithm> #define M 510 using namespace std; int map[M][M],f[M],vis[M][M],flag[M],mn[M],mx[M],n,m; int a[5]={0,0,0,1,-1}; int b[5]={0,1,-1,0,0}; vector<int> grap[M]; int out(int x,int y) { if(x<1||x>n||y<1||y>m)return 1; return 0; } void dfs(int num,int x,int y) { if(x==n) { grap[num].push_back(y); flag[y]=1; } for(int i=1;i<=4;i++) { int xx=x+a[i]; int yy=y+b[i]; if(!out(xx,yy)&&!vis[xx][yy]&&map[xx][yy]<map[x][y]) { vis[xx][yy]=1; dfs(num,xx,yy); } } } void DP() { memset(f,0x3f3f3f3f,sizeof(f)); f[0]=0; for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) if(i>=mn[j]&&i<=mx[j]) f[i]=min(f[i],f[mn[j]-1]+1); printf("1\n%d",f[m]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&map[i][j]); for(int i=1;i<=m;i++) { memset(vis,0,sizeof(vis)); vis[1][i]=1; dfs(i,1,i); } memset(mn,0x3f3f3f3f,sizeof(mn)); int tot=0; for(int i=1;i<=m;i++) if(flag[i])tot++; if(tot!=m) { printf("0\n%d",m-tot); return 0; } for(int i=1;i<=m;i++) for(int j=0;j<grap[i].size();j++) { mn[i]=min(mn[i],grap[i][j]); mx[i]=max(mx[i],grap[i][j]); } DP(); return 0; }
View Code
相关文章推荐
- 使用adagio包解决背包问题
- CALayer 图层简介
- Python学习笔记6:Python序列
- 二叉树的层次遍历----java实现
- iOS --- 扩展和泛型(swift2.3)
- 图的连通性问题之强连通分量初步
- jsp前3章试题分析
- NSURLConnection简单使用
- pyqt 加载资源文件
- Git push出错
- Vigenère 密码(luogu 1079)
- storyboard文件的认识
- Flex 布局教程:语法篇
- 【NOIP2015TGD2T1】poj3258 River Hopscotch
- php配置thinkphp
- leetcode Sum of Two Integers
- C修饰符const
- 《OD学hadoop》第三周0709
- Linux : Bridge support not available: brctl not found
- hdu3538(最短哈密顿路径)