洛谷1514 引水入域 dp+记忆化搜索
题目链接:https://www.luogu.com.cn/problem/P1514
题意大致是:给定一个(n,m)的数值矩阵,可以在第一行建造水库,如果一个格子周围的某格子值小于它,那水就可以流到它周围的那个格子,问需要在第一行建造多少水库使得最后一行能够被完全覆盖,如果不能完全覆盖就求出不能覆盖的格子的数量。
主要思路就是在第一行每个点出发的水能到达第n行的区间可以获得(可以用反证法证明每个点出发的水如果能到达第n行那么它的覆盖区间一定是连续的),如果能够完全覆盖第n行则用最小区间数覆盖可以求出最少需要多少个点可以覆盖第n行,
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a))
#define prime1 1e9+7
#define prime2 1e9+9
#define scand(x) scanf("%llf",&x)
#define f(i,a,b) for(int i=a;i<=b;i++)
#define scan(a) scanf("%d",&a)
#define dbg(args) cout<<#args<<":"<<args<<endl;
#define pb(i) push_back(i)
#define ppb(x) pop_back(x)
#define inf 0x3f3f3f3f
#define maxn 1005
int n,m,t,a[maxn][maxn],l[maxn][maxn],r[maxn][maxn],vis[maxn][maxn];
//l[i][j]从(i,j)位置出发的水最多能覆盖到最后一行的左端的位置,
//r[i][j]从(i,j)位置出发的水最多能覆盖到最后一行的最右端的位置
int dir[][]={{,},{,-},{-,},{,}};
void dfs(int x,int y)
{
vis[x][y]=true;//表明(x,y)位置的l,r信息都被处理过
int xx,yy;
f(i,,)
{
xx=x+dir[i][];
yy=y+dir[i][];
if(xx<=||xx>n||yy<=||yy>m)continue;
if(a[xx][yy]>=a[x][y])continue;
if(!vis[xx][yy])
{
dfs(xx,yy);
}
l[x][y]=min(l[x][y],l[xx][yy]);
r[x][y]=max(r[x][y],r[xx][yy]);
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
std::ios::sync_with_stdio(false);
scan(n);
scan(m);
f(i,,n)
f(j,,m)
{
scan(a[i][j]);
}
mem(l,inf);
mem(r,-inf);
f(,,m)
{
l[n][i]=r[n][i]=i;//最下面一层,初始情况区间只覆盖自己
}
f(i,,m)
{
if(!vis[][i])
dfs(,i);
}
bool flag=true;
int cnt=;
f(i,,m)
{
if(!vis[n][i])
{
flag=false;
cnt++;
}
}
if(!flag)
{
pf("0\n%d",cnt);//有多少个点无法覆盖
}
else
{
int num=;
int left=,maxr=;//最小区间数覆盖
while(left<=m)
{
maxr=;
f(i,,m)
{
if(l[][i]<=left)//找到覆盖left点的区间右端值的最大值
maxr=max(maxr,r[][i]);
}
left=maxr+;
num++;
}
pf("1\n%d\n",num);
/* f(i,1,m)
{
pf("%d %d\n",l[1][i],r[1][i]);
}*/
}
return ;
}
洛谷1514 引水入域 dp+记忆化搜索的更多相关文章
- 【题解】洛谷P3953 [NOIP2017TG] 逛公园(记忆化搜索+SPFA)
题目来源:洛谷P3953 思路 先用SPFA求一遍最短路 在求最短路的同时可以把所有点到终点的最短路求出来 dis数组 注意要反向SPFA 因为从起点开始可能会走到一些奇怪的路上导致时间负责度增加 ...
- luogu1514 [NOIp2010]引水入城 (bfs+记忆化搜索)
我们先bfs一下看看是否能到最底下的所有点 如果不能的话,直接把不能到的那几个数一数就行了 如果能的话: 可以发现(并不可以)某格能到达的最底下的格子一定是一个连续的区间 (因为如果不连续的话,我们先 ...
- [NOIP2010] 引水入城 贪心 + 记忆化搜索
---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...
- 洛谷P4133 [BJOI2012]最多的方案(记忆化搜索)
题意 题目链接 求出把$n$分解为斐波那契数的方案数,方案两两不同的定义是分解出来的数不完全相同 Sol 这种题,直接爆搜啊... 打表后不难发现$<=1e18$的fib数只有88个 最先想到的 ...
- 洛谷P1514 引水入城
洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...
- 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索
题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...
- 【BZOJ】1415 [Noi2005]聪聪和可可 期望DP+记忆化搜索
[题意]给定无向图,聪聪和可可各自位于一点,可可每单位时间随机向周围走一步或停留,聪聪每单位时间追两步(先走),问追到可可的期望时间.n<=1000. [算法]期望DP+记忆化搜索 [题解]首先 ...
- [题解](树形dp/记忆化搜索)luogu_P1040_加分二叉树
树形dp/记忆化搜索 首先可以看出树形dp,因为第一个问题并不需要知道子树的样子, 然而第二个输出前序遍历,必须知道每个子树的根节点,需要在树形dp过程中记录,递归输出 那么如何求最大加分树——根据中 ...
- poj1664 dp记忆化搜索
http://poj.org/problem?id=1664 Description 把M个相同的苹果放在N个相同的盘子里,同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5.1.1和1 ...
随机推荐
- Gre 隧道与 Keepalived
这一篇文章是做了不少功课的. 什么是 Gre 隧道 什么是 Vrrp KeepAlived 是什么 用Keepalived 怎么玩 附录 什么是 Gre 隧道 GRE 隧道是一种 IP-2-IP 的隧 ...
- 从iPhone X到三星S9,为何现在山寨还能如此肆无忌惮?
X到三星S9,为何现在山寨还能如此肆无忌惮?" title="从iPhone X到三星S9,为何现在山寨还能如此肆无忌惮?"> 曾几何时,以"土豪金&qu ...
- windowserver 2012安装openssh
下载https://github.com/PowerShell/Win32-OpenSSH/releases解压放到C:\Program Files\OpenSSH-Win64 进入到C:\Progr ...
- ThinkPHP判断更新是否成功的正确方法
如何判断一个更新操作是否成功 $Model = D('Blog'); $data['id'] = 10; $data['name'] = 'update name'; $result = $Model ...
- JAVA如何判断两个字符串是否相等
==比较引用,equals 比较值 1.java中字符串的比较:== 我们经常习惯性的写上if(str1==str2),这种写法在java中可能会带来问题 example1: String a=&qu ...
- 虚拟机+server03系统+sql的安装
教程: 首先安装虚拟机 然后安装server系统 最后完成sql的安装 https://download.pchome.net/system/sysenhance/detail-4673.html 虚 ...
- 吐槽苹果开放接口のappleid登陆
这里吐槽一下苹果的开发文档,一切源于前段时间,公司的产品app(某知名资讯app)要接入苹果登陆(ios13发布以来,apple就流氓要求新上线的app,如果有第三方登陆的话,必须要接入appleid ...
- APScheduler使用总结
安装 pip install apscheduler APScheduler组件 1.triggers(触发器) 触发器中包含调度逻辑,每个作业都由自己的触发器来决定下次运行时间.除了他们自己初始配置 ...
- Java enum枚举在实际项目中的常用方法
在项目实际开发过程中,经常会遇到对某些固定的值.字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目 ...
- js笔记系列之--时间及时间戳
js入门系列之 时间及时间戳 时间及时间戳 时间及时间戳是js里面很常见的一个概念,在我们写前端页面的时候,经常会遇到需要获取当前时间的情况,所以,了解js中的时间概念非常重要.而时间戳是指格林威治时 ...