【题目链接】:http://noi.qz5z.com/viewtask.asp?id=z10

【题解】



对于第一问:从最上面那m个格子开始进行广搜就可以了;

然后看一下最下面那一行有没有被全部覆盖;

对于第二问:

要先明确;从最上面的那m个格子中的任意一个点开始,在最下面的沙漠中行成的覆盖段一定是连续的一段;(有解的前提下);

证明:

假设最上面的格子x开始进行广搜在最下面形成了两段不连续的区间

a..b c..d (b小于c)

则必然在最上面的m个点中有一个点或多个点,能覆盖b..c这个区间;



但是如果那样覆盖的话,如上图所示,那个点(或多个点)在往下覆盖的时候肯定会和x往下覆盖的路径发生重叠,而既然那个点能往下走,为什么x号节点不能往下走?这就出现矛盾了;所以x格子不可能在最下面形成不连续的两段区间(或多段),则它只能形成一段连续的区间.

则我们在判断完有解之后;

再一个一个地以最上面那个湖泊的点为起点进行广搜,到最下面;看它能覆盖的区间是什么->求出m个区间;

然后用这m个区间进行动规以求覆盖1..m所需要的最少区间数->区间数对应蓄水厂数目;

f[i] = min(f[l[k]-1]+1,f[i]);其中r[k]>=i;



【完整代码】

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second typedef pair<int,int> pii;
typedef pair<LL,LL> pll; void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} const int MAXN = 500+10;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); int n,m;
int a[MAXN][MAXN];
int flag[MAXN][MAXN];
bool bo[MAXN][MAXN];
int tag = 0;
queue <pii> dl; void bfs()
{
while (!dl.empty())
{
int x = dl.front().fi,y = dl.front().se;
dl.pop();
rep1(k,1,4)
{
int tx = x+dx[k],ty = y+dy[k];
if (bo[tx][ty])
{
if (a[tx][ty]<a[x][y] && flag[tx][ty]!=tag)
{
flag[tx][ty] = tag;
dl.push(mp(tx,ty));
}
}
}
}
} int main()
{
// freopen("F:\\rush.txt","r",stdin);
memset(bo,false,sizeof(bo));
rei(n);rei(m);
rep1(i,1,n)
rep1(j,1,m)
rei(a[i][j]),bo[i][j] = true;
memset(flag,0,sizeof(flag));
tag++;
rep1(i,1,m)
{
flag[1][i] = tag;
dl.push(mp(1,i));
}
bfs();
int cnt = 0;
rep1(i,1,m)
if (flag[n][i]==0)
cnt++;
if (cnt)
{
puts("0");
printf("%d\n",cnt);
return 0;
}
else
{
vector <pii> a;
rep1(i,1,m)
{
tag++;
flag[1][i] = tag;
dl.push(mp(1,i));
bfs();
pii temp;
rep1(j,1,m)
if (flag[n][j]==tag)
{
temp.fi=j;
break;
}
rep2(j,m,1)
if (flag[n][j]==tag)
{
temp.se = j;
break;
}
a.pb(temp);
}
int f[MAXN],len = a.size();
memset(f,0x3f3f3f3f,sizeof f);
f[0] = 0;
rep1(i,1,m)
rep1(j,0,len-1)
if (a[j].se>=i)
f[i] = min(f[i],f[a[j].fi-1]+1);
puts("1");
printf("%d\n",f[m]);
}
return 0;
}

最新文章

  1. 通过jquery js 实现幻灯片切换轮播效果
  2. 小议jQuery插件开发
  3. GJM :多人在线游戏的设计思路
  4. Python 之Ajax
  5. 在opencv3中实现机器学习之:利用逻辑斯谛回归(logistic regression)分类
  6. JEECMS插件开发
  7. 【转】solr+ajax智能拼音详解---solr跨域请求
  8. oracle PL/SQL基础编程
  9. IBatis.Net 表连接查询(五)
  10. AngularJS 的安全Apply
  11. CF 560e Gerald and Giant Chess
  12. Linux下的定时器:alarm()与setitimer()
  13. 13-UIKit(tableviewcell贴图、手势GestureRecognizer、transform变形)
  14. 【转】android加载大量图片内存溢出的三种解决办法
  15. Java多线程:线程同步与关键字synchronized
  16. eclipse如何导入项目和文件
  17. Linux下挂载新硬盘方法
  18. SSH构造struts2项目
  19. hadoop常用操作命令
  20. 百度AI开放平台 情感倾向分析实例以及gbk编码解决

热门文章

  1. Android学习笔记技巧之给文本加边框
  2. Date类的用法
  3. 用Zebra打造Linux下小型路由器
  4. HTML5的设计目的是为了在移动设备上支持多媒体
  5. 03002_MySQL数据库的安装和配置
  6. Android 调试出现 could not get wglGetExtensionsStringARB
  7. 请使劲回答一个关于UNIX/Linux自己主动扩展stack的问题
  8. HDF文件的显示策略
  9. 【例题 7-8 UVA - 10603】Fill
  10. JSP学习 —— 开篇:JSP,servlet容器,Tomcat,servlet容器之间的关系