P1545 [USACO04DEC] Dividing the Path G 题解

最近开始快刷蓝紫黑了,做完会写题解交上来。

题目传送门

题意

一条长为 \(L(1 \le L \le 10^6 , 2 | L)\) 的线段上,给出 \(N(1 \le N \le 10^3)\) 个可能相交的子段 \([S_i,E_i]\),现要求用若干个长度在 \([2a,2b]\) 中且为偶数的小线段覆盖整个大线段。

要求:

  • 整个大线段都要被覆盖。
  • 用来覆盖的小线段不相交。
  • 每个子段能且仅能被唯一一个小线段覆盖。
  • 小线段的范围不能超出大线段。

求出最少用来覆盖的小线段的个数。

分析

这道题暴力 \(O(L^2)\) 是好写的,设 \(dp_i\) 表示覆盖 \([0,i]\) 所需的小线段个数(显然 \(i\) 必须为某个子段的端点),答案明显为 \(dp_L\) ,边界也是显而易见的:\(dp_0=0\) 。

转移有如下式子:

\[dp_i=\min_{j=i-2b,2|j}^{i-2a}(dp_j+1)
\]

然后交了一发就过了。

虽然数据较水,但我们仍需要考虑正解。

转移方程中,取最小值里的 \(+1\) 可以提出来,所以我们实际上是在求 \(\min dp_j\) 。

我们其实会很容易地发现这其实就是在一段区间里取最小值。

每次转移完当前点的值,我们都会把它当作下次转移时的区间里的一部分。

提炼一下:区间取 \(\min\),单点修改。

线段树可以很方便的处理掉,复杂度 \(O(L\log L)\) 。

AC Code
#include<bits/stdc++.h>
#define int long long
#define rep(I,A,B) for(int I=(A);I<=(B);++I)
#define per(I,A,B) for(int I=(A);I>=(B);--I)
#define el puts("")
#define Yuki return
#define daisuki 0
#define debug puts("SKIRK")
#define none 'N'
#define ed '\n'
#define pc putchar
using namespace std;
using pii=pair<int,int>;
//fastIO start
template<typename T>
void read(T &x){
x=0;bool f=0;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=1;
for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
if(f)x=-x;
}
template<typename T,typename ...Args>
void read(T &x,Args &...args){
read(x),read(args...);
}
template<typename T>
void write(T x,char ch=' '){
if(x<0)putchar('-'),x=-x;
static short st[70],tp;
do st[++tp]=x%10,x/=10;while(x);
while(tp)putchar(st[tp--]|48);
if(ch!=none)putchar(ch);
}
void writes(string str){
rep(i,0,str.size()-1)putchar(str[i]);
}
void writec(char chs){
putchar(chs);
}
//fastIO end
const int N=1e3+5;
const int L=1e6+5;
const int inf=0x3f3f3f3f;
struct edge{
int s,e;
}p[N];
int n,l,a,b;
bool vis[L];
int dp[L];
struct node{
int l,r,mn;
}tr[L<<2];
void build(int p,int l,int r){
tr[p].l=l;
tr[p].r=r;
tr[p].mn=inf;
if(l==r)return ;
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
int query(int p,int L,int R){
int l=tr[p].l;
int r=tr[p].r;
if(r<L||l>R)return inf;
if(L<=l&&r<=R)return tr[p].mn;
return min(query(p<<1,L,R),query(p<<1|1,L,R));
}
void modify(int p,int L,int v){
int l=tr[p].l;
int r=tr[p].r;
if(r<L||l>L)return ;
if(l==r)return tr[p].mn=v,void();
modify(p<<1,L,v);
modify(p<<1|1,L,v);
tr[p].mn=min(tr[p<<1].mn,tr[p<<1|1].mn);
}
signed main(){
read(n,l,a,b);
rep(i,1,n){
read(p[i].s,p[i].e);
rep(j,p[i].s+1,p[i].e-1)vis[j]=1;
}
memset(dp,0x3f,sizeof(dp));
dp[0]=0;
build(1,0,l);
modify(1,0,0);
for(int i=2;i<=l;i+=2){
if(vis[i])continue;
dp[i]=query(1,max(i-2*b,0ll),i-2*a)+1;
modify(1,i,dp[i]);
// rep(j,a,b){ //暴力转移
// int k=i-j*2;
// if(k<0)continue;
// Min(dp[i],dp[k]+1);
// }
}
if(dp[l]>=inf)dp[l]=-1;
write(dp[l]);
Yuki daisuki;//Yuki真的是太可爱了捏
}
//by oSomiwww

P1545 [USACO04DEC] Dividing the Path G 题解的更多相关文章

  1. poj 2373 Dividing the Path

    Dividing the Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2858   Accepted: 1064 ...

  2. POJ 2373 Dividing the Path(DP + 单调队列)

    POJ 2373 Dividing the Path 描述 农夫约翰的牛发现,在他的田里沿着山脊生长的三叶草是特别好的.为了给三叶草浇水,农夫约翰在山脊上安装了喷水器. 为了使安装更容易,每个喷头必须 ...

  3. poj2373 Dividing the Path

    Dividing the Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5060   Accepted: 1782 ...

  4. 洛谷P3104 Counting Friends G 题解

    题目 [USACO14MAR]Counting Friends G 题解 这道题我们可以将 \((n+1)\) 个边依次去掉,然后分别判断去掉后是否能满足.注意到一点, \(n\) 个奶牛的朋友之和必 ...

  5. 洛谷P2115 Sabotage G 题解

    题目 [USACO14MAR]Sabotage G 题解 本蒟蒻又来了,这道题可以用二分答案来解决.我们可以设答案最小平均产奶量为 \(x \ (x \in[1,10000])\) .然后二分搜索 \ ...

  6. POJ 2373 Dividing the Path (单调队列优化DP)题解

    思路: 设dp[i]为覆盖i所用的最小数量,那么dp[i] = min(dp[k] + 1),其中i - 2b <= k <= i -2a,所以可以手动开一个单调递增的队列,队首元素就是k ...

  7. USACO07NOV Cow Relays G 题解

    题目 For their physical fitness program, \(N (2 ≤ N ≤ 1,000,000)\) cows have decided to run a relay ra ...

  8. P2882 Face The Right Way G 题解

    题目 Farmer John has arranged his N \((1 ≤ N ≤ 5,000)\) cows in a row and many of them are facing forw ...

  9. Hdoj 2454.Degree Sequence of Graph G 题解

    Problem Description Wang Haiyang is a strong and optimistic Chinese youngster. Although born and bro ...

  10. Dividing the Path POJ - 2373 dp

    题意:你有无数个长度可变的区间d  满足 2a<=d<=2b且为偶数. 现在要你用这些区间填满一条长为L(L<1e6且保证是偶数)的长线段. 满足以下要求: 1.可变区间之间不能有 ...

随机推荐

  1. 前端开发系列090-Node篇之Event

    一.EventEmitter介绍 Node中的event模块实现了事件处理相关功能,在该模块中定义了EventEmitter类. 在Node中,所有可能触发事件的对象都是继承了EventEmitter ...

  2. 支撑 1300 万月活的幕后真相:Figma 是怎么把核心服务搬上 EKS 的?

    本文由 CloudPilot AI 编译,转载请联系marketing@cloudpilot.ai 近日,设计软件新贵 Figma 正式递交 IPO 申请,有望成为 2025 年规模最大的科技上市案. ...

  3. windows 建立ftp 服务器

    windows 建立 FTP服务器 复杂的方法 FQ博客 重要的时账户的建立.与访问权限的修改 简单的方法 直接下载一个ftp软件 https://filezilla-project.org/

  4. java 省略 System 写法

    简介 RT code import static java.lang.System.*; 可以直接使用 out.println("ddd");

  5. 产品更新丨谷云科技ETLCloud 3.9.3 版本发布

    在数字化集成领域不断探索创新的谷云科技,为持续提升 ETLCloud 集成平台的性能和用户体验,于近期发布了 3.9.3 版本.本次迭代带来了新功能.对现有组件进行了优化,同时修复了多个影响系统稳定性 ...

  6. 资深ETL工程师经验分享:ETL项目的5大挑战与策略

    ETL项目的重要性及其复杂性 在我十多年的数据仓库建设经验中,ETL(Extract, Transform, Load)一直是最具挑战性的环节之一.简单来说,ETL就是将分散在各个业务系统中的数据抽取 ...

  7. 4月18日“RestCloud ETL社区版”重磅推出

    - -/ 新一代ETL数据集成平台 /-- 数据价值的挖掘应用为当今社会的数字化进程开辟出了一个新的发展方向,未来更多的企业将逐渐进行数字化转型,以便于参与到数据产业体系当中,从而获得更强的创新能力和 ...

  8. mysql中date_format函数格式化日期,如何精确到毫秒?

    直接看官网文档 : https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format ...

  9. freeswitch笔记(5)-小型呼叫中心设计思路

    这一篇用esl实战一把,利用esl client来实现一个小型呼叫中心的原型,先看看下面这张图: 企业通常会对外公布一个400之类的服务电话,当用户拨打这个电话时,实际上背后是一堆客服妹纸带着耳麦通过 ...

  10. C++迭代器iterator详解

    https://blog.csdn.net/QIANGWEIYUAN/article/details/89184546?utm_medium=distribute.pc_relevant.none-t ...