[洛谷1868]饥饿的奶牛
思路:
动态规划。
类似于线段覆盖,首先对每个区间的右端点从小到大排好序。
对于每个区间si,状态转移方程为fsi.r=max。
对于这个max,我们可以用一个树状数组来维护前缀最大值。
有n组区间,区间范围是0\sim m,渐近时间复杂度为O(n\log m)。
另外注意区间有可能为0,用树状数组不好维护,因此我们可以将所有的端点+1。
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<algorithm> 5 inline int getint() { 6 char ch; 7 while(!isdigit(ch=getchar())); 8 int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=150000,M=3000002; 13 int m=0; 14 class FenwickTree { 15 private: 16 int val[M]; 17 int lowbit(const int x) { 18 return x&-x; 19 } 20 public: 21 FenwickTree() { 22 memset(val,0,sizeof val); 23 } 24 void modify(int p,const int x) { 25 while(p<=m) { 26 val[p]=std::max(val[p],x); 27 p+=lowbit(p); 28 } 29 } 30 int query(int p) { 31 int ret=0; 32 while(p) { 33 ret=std::max(ret,val[p]); 34 p-=lowbit(p); 35 } 36 return ret; 37 } 38 }; 39 FenwickTree t; 40 int f[M]={0}; 41 struct Segment { 42 int x,y; 43 bool operator < (const Segment &another) const { 44 return y<another.y; 45 } 46 }; 47 Segment s[N]; 48 int main() { 49 int n=getint(); 50 for(register int i=0;i<n;i++) { 51 s[i].x=getint()+1; 52 s[i].y=getint()+1; 53 m=std::max(m,s[i].y); 54 } 55 std::sort(&s[0],&s[n]); 56 int ans=0; 57 for(register int i=0;i<n;i++) { 58 int &x=s[i].x,&y=s[i].y; 59 int tmp=t.query(x-1)+y-x+1; 60 if(tmp>f[y]) { 61 t.modify(y,f[y]=tmp); 62 ans=std::max(ans,tmp); 63 } 64 } 65 printf("%d\n",ans); 66 return 0; 67 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· Supergateway:MCP服务器的远程调试与集成工具