首页 > 其他分享 >P1545 [USACO04DEC] Dividing the Path G 题解

P1545 [USACO04DEC] Dividing the Path G 题解

时间:2023-06-03 10:33:57浏览次数:46  
标签:int 题解 线段 tr P1545 res 区间 Path dp

丢一发好理解又好写的线段树优化dp。

题目传送门

简要题意

给定一个长为 \(l\) 的线段,求出尽量少的不相交区间覆盖整段线段,要求题目给的所有子区间只被 \(1\) 个区间覆盖。

分析

显然题目给的子区间 \([s, e]\) 中只有 \(s\) 和 \(e\) 端点能作为线段端点,所以我们应该给 \([s + 1, e + 1]\) 打上标记,这些不能作为线段端点。
令 \(dp_i\) 为覆盖 \([0, i]\) 的最小的线段数量,要求的就是 \(\min (dp_j) + 1, j \in [i - a * 2, i - b * 2]\)。
可以很轻易的写出一段暴力程序。

dp[0] = 0;
for(int i = 2; i <= l; i += 2)
{
	if(flag[i]) continue;
	for(int k = a; k <= b; k ++)
	{
		int j = i - k * 2; // 在i, j 中间放一个线段
		if(j < 0) break;
		dp[i] = min(dp[i], dp[j] + 1);
	}
}

发现该算法的瓶颈会在枚举 \(k\) 的复杂度太高了,考虑优化掉。
区间最小值?线段树?
每次取出区间中的最小值算出 \(dp_i\) 递推下去就行。
代码就变成了这样:

	for(int i = a * 2; i <= l; i += 2)
	{
		if(flag[i]) continue;
		int ql = max(0, i - 2 * b), qr = i - 2 * a;
		dp[i] = query(ql, qr, 1) + 1;
		update(i, dp[i], 1);
	}

写一棵可爱的线段树就可以拉。
code

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5, INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
int n, l, a, b;
bool flag[N];
int dp[N];
struct segtree
{
	int l, r, val;
	#define l(x) tr[x].l
	#define r(x) tr[x].r
	#define val(x) tr[x].val
} tr[N << 2];
void pushup(int x)
{
	val(x) = min(val(x << 1), val(x << 1 | 1));
}
void build(int l, int r, int x)
{
	l(x) = l, r(x) = r, val(x) = INF;
	if(l == r) return;
	int mid = l + r >> 1;
	build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
}
void update(int pos, int v, int x)
{
	if(l(x) == r(x))
	{
		val(x) = v;
		return;
	}
	int mid = l(x) + r(x) >> 1;
	if(mid >= pos) update(pos, v, x << 1);
	else update(pos, v, x << 1 | 1);
	pushup(x);
}
int query(int l, int r, int x)
{
	if(l <= l(x) && r(x) <= r) return val(x);
	int mid = l(x) + r(x) >> 1, res = INF;
	if(l <= mid) res = query(l, r, x << 1);
	if(r > mid) res = min(res ,query(l, r, x << 1 | 1));
	return res;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
	cin >> n >> l >> a >> b;
	for(int i = 1; i <= n; i ++)
	{
		int x, y;
		cin >> x >> y;
		for(int j = x + 1; j <= y - 1; j ++) flag[j] = true;
	}
	build(0, l, 1);
	update(0, 0, 1);
	for(int i = a * 2; i <= l; i += 2)
	{
		if(flag[i]) continue;
		int ql = max(0, i - 2 * b), qr = i - 2 * a;
		dp[i] = query(ql, qr, 1) + 1;
		update(i, dp[i], 1);
	}
	if(dp[l] >= INF) dp[l] = -1;
	cout << dp[l] << '\n';
    return 0;
}

标签:int,题解,线段,tr,P1545,res,区间,Path,dp
From: https://www.cnblogs.com/Svemit/p/17453426.html

相关文章

  • 【Pytorch】ValueError: not enough values to unpack (expected 2, got 1)问题解决
    在运行开源项目时出现了这个问题,网上很多说删回车或者都改成英文符号,但是我都试了,没用后来自己摸索出的方法是:先更改数据集的格式,之前分隔符是\t,把数据集中的分隔符改成空格,再把语句中的\t也换成空格,然后就不会报错了。改前:改后:......
  • python pip安装库时遇到fatal error的问题解决
    当时的图片没有留,写点东西做备忘吧。一开始尝试pipinstallxx库,cmd提示pip不是批处理文件或命令,解决方法:去属性的高级设置里,在用户变量的Path里增加pip所在的路径,如果不知道pip在哪里,就在cmd里输入wherepip查询,查不到就在文件管理里用查询。解决这个问题后,再尝试安装,错误提示......
  • 杂项题解
    JOISC2017_JAbduction2由于权值较高的路不会被权值较低的路线影响,所以首先考虑将\(h+w\)条边按照权值降序排序,再考虑应该的最优决策方案。注意到每一条路都横跨原始的矩形,这样以出发点为中心向上下左右发散就会有4条边构成一个小矩形。考虑维护这个矩形每条边的最大路径......
  • [ROI 2018] Innophone 题解
    [ROI2018]Innophone看了半天网上仅有的一篇题解……才堪堪写出来不过在LOJ上看提交,全是KTT,看得我瑟瑟发抖(不会题意翻译在平面上有一些点,你需要在这个平面上任意确定一个点(不要求是给定的点),定义其贡献为横坐标\(\times\)其右侧的点\(+\)纵坐标\(\times\)其左上方的......
  • docker apt-get update失败问题解决
    一、问题描述docker容器相当于linux系统的精简版,内部很多指令是无法直接使用的,例如vim指令,为了使用vim指令,我们需要进入容器内部进行安装,安装步骤为:apt-getupdateapt-getinstallvim很多时候我们发现安装会失败,这里是由于下载源问题。二、解决方案1.进入宿主机下cd/e......
  • 问题解决:Ubuntu18.04显示器分辨率不正常
    在Ubuntu18.04下出现显示器分辨率不正确的情况,只能选择1024x768的分辨率,没有其它选项,显示器本身可以支持1920x1080的分辨率。经查询,采用cvt,xrandr的方法不成功,显示xrandr:Failedtogetsizeofgammaforoutputdefault的错误,采用修改grub的方法如下解决方法修改/etc/defaul......
  • k8s问题解决 - 删除命名空间长时间处于terminating状态
    一行命令解决,注意替换两处待删命名空间字样kubectlgetnamespace"待删命名空间"-ojson\|tr-d"\n"|sed"s/\"finalizers\":\[[^]]\+\]/\"finalizers\":[]/"\|kubectlreplace--raw/api/v1/namespaces/待删命名空间/finali......
  • [WC/CTS2023] 树据结构 题解
    题目描述作为一个熟练的OI选手,你对数据结构的各种题型早已轻车熟路,比赛中只要碰到数据结构题就能三下五除二轻松搞定。这一天,你翻开OJ,看到了这道题:给定\(n\)个点的有根树,点编号为\(1,2,\dots,n\),\(1\)为根。每条边上有一个\(1\)至\(n-1\)的两两不同的权值。维护......
  • 启动HBase时提示SLF4J: Class path contains multiple SLF4J bindings的解决方法
    启动hbase报错:“SLF4J:ClasspathcontainsmultipleSLF4Jbindings.”解决方法cd/home/opt/hbase-2.2.3/lib/client-facing-thirdpartymvslf4j-log4j12-1.7.25.jarslf4j-log4j12-1.7.25-copy修改了hbase中的文件名,保留了hadoop的,这个会有问题,一个当启动hbase的reg会报错这......
  • Razor Pages本地IIS服务器部署流程及部分问题解决方法
     记录一下自己在本地IIS服务器部署的基本流程:添加IIS服务器控制面板>>程序和功能 启用或关闭windows功能>>勾选相关功能   网站部署将项目发布(publish)至本地文件夹:在包含.sln文件的目录下打开终端,输入dotnetpublish-cdebug--no-self-contained......