1. 程式人生 > >Codeforces Round #422 C

Codeforces Round #422 C

span pre def name turn contest algo 遍歷 hack

Hacker, pack your bags!

題意:給n個區間,每個區間的長度為ri-li+1,權值為ci,選取2個不相交的區間,長度加起來為x,且權值和最小

思路:遍歷 l ,vi[l]存起點為l的區間的權值最小值,每次加入li==l的區間更新vi的值,更新後再更新ri==l-1的答案,這樣可以保證,每次選擇一個區間後,從vi裏選擇的另一個區間一定是不相交的

AC代碼:

#include<bits/stdc++.h>
#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include 
"string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) #define mp(x,y) make_pair(x,y) #define pb push_back const long
long INF = 1e18+1LL; const int inf = 1e9+1e8; using namespace std; const int N=1e5+100; vector<pair<ll,ll> > vexl[2*N],vexr[2*N]; ll n,x,vi[2*N],mk[2*N]; int main(){ for(int i=0; i<=2e5; ++i) vi[i]=2LL*inf; //for(int i=1; i<=10; ++i) cout<<vi[i]<<" "; ll ans=2LL*inf; scanf(
"%lld%lld",&n,&x); int li,ri,ma=0; ll ci; for(int i=1; i<=n; ++i){ scanf("%d%d%lld",&li,&ri,&ci); ma=max(ma,ri); vexl[li].pb(mp(ri,ci)); vexr[ri].pb(mp(li,ci)); } for(int l=ma; l>0; --l){ for(auto j :vexl[l]){ int len=j.first-l+1; mk[len]=1,vi[len]=min(vi[len],j.second); //cout<<j.second<<endl; } int r=l-1; for(auto j :vexr[r]){ int len=x-(r-j.first+1); if(len>0 && mk[len]){ ans=min(ans,j.second+vi[len]); //cout<<len<<" "<<r<<" "<<j.second<<" "<<vi[len]<<endl; } } } if(ans==2LL*inf) printf("-1"); else printf("%lld",ans); return 0; }

Codeforces Round #422 C