标签:ota 技术 c++ test points font other pre 编号
我们需要从0走到m
那么如果一个任务是是正向的
a->b a<=b的话,那么我们可以顺路得完成,不用多余的路
1和2都被顺路完成
而3是从0-m是最长的,我们就可以知道,如果任务是a->b a<=b的都可以被忽略,因为都可以被顺路完成
那么我们现在就只用考虑a->b a>b 倒着走的
逆向的情况根据刚刚我们正向分析的性质,也只到包含关系的内部可以省略
5可以省略
所以最后我们只用考虑的情况是
考虑我们是把4完成了,再完成5,还是4,5一起完成?
我们发现4,5一起完成会少走他们交集的那么段路
并且我们发现多个情况,也是一起完成是会更优
所以我们就有了贪心策略
只有有交集的都一起完成,否则就单独完成
附上代码:
#include<bits/stdc++.h> using namespace std; const int N=3e5+12; int n,m; struct node { int l,r; bool operator < (const node & other )const { if(l==other.l) {return r<other.r;} return l< other.l; } }edge[N]; int cnt; long long f[N]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d%d",&n,&m); int a,b; for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); if(a<=b) continue; edge[++cnt]=(node){b,a}; } sort(edge+1,edge+cnt+1); int mx=0;int temp=cnt;cnt=0; for(int i=1;i<=temp;i++) { if(edge[i].r<=mx) continue; edge[++cnt]=edge[i]; mx=max(mx,edge[i].r); } f[1]=1LL*edge[1].l+(long long)(edge[1].r-edge[1].l)*3; int l=edge[1].l,r=edge[1].r;int id=1; for(int i=2;i<=cnt;i++) { if(edge[i].l<=r) { f[i]=f[id-1]+(long long)(edge[i].r-l)*3+1LL*(edge[id].l-edge[id-1].r); r=max(r,edge[i].r); } else { f[i]=f[i-1]+(long long)(edge[i].r-edge[i].l)*3*1LL+1LL*(edge[i].l-edge[i-1].r); l=edge[i].l;r=edge[i].r;id=i; } } long long ans=f[cnt]+1LL*(m-edge[cnt].r); printf("%lld\n",ans); return 0; }
标签:ota 技术 c++ test points font other pre 编号
原文地址:https://www.cnblogs.com/Heey/p/9125993.html