Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) D. Jury Meeting

题意:相当于n个小岛,每个岛上一个人,都要去0岛,给出m张机票的出发日期,出发地,目的地,价格,问是否存在2*n张机票让n个人一起呆在0岛上最少k天,输出最少花费

思路:贪心,我们分别求出去和回来的,在满足n个人都到了的该日期的最少飞机价格,然后我们知道,去的时候,比如我在第8天全都到了,那么第九天买的所有机票,和第八天是一样的,取个最小值,回来的话,相反

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+100;
 4 typedef long long ll;
 5 const ll INF=1e18;
 6 
 7 struct node{
 8     ll d,f,t,c;
 9 }a[N];
10 ll b[N];
11 ll dp[1000006],dp1[1000005];
12 
13 bool cmp(node p,node q){
14     return p.d<q.d;
15 }
16 int main(){
17     int n,m,k;
18     ll x=1000000,y=-1;
19     cin>>n>>m>>k;
20     for(int i=1;i<=m;i++){
21         scanf("%lld%lld%lld%lld",&a[i].d,&a[i].f,&a[i].t,&a[i].c);
22     }
23     sort(a+1,a+1+m,cmp);
24     for(int i=1;i<=1000001;i++) b[i]=-1,dp[i]=INF;
25     ll sum=0,s=0;
26     for(int i=1;i<=m;i++){//处理去的机票
27         if(a[i].f==0) continue ;
28         if(b[a[i].f]==-1) {
29             s++;b[a[i].f]=a[i].c;sum+=a[i].c;
30         }
31         else {
32             if(b[a[i].f]>a[i].c){
33                 sum-=b[a[i].f];
34                 sum+=a[i].c;
35                 b[a[i].f]=a[i].c;
36             }
37         }
38         if(s==n){
39             dp[a[i].d]=sum;
40             x=min(x,a[i].d);
41         }
42     }
43     for(int i=1;i<=1000001;i++) b[i]=-1,dp1[i]=INF;
44     sum=0;s=0;
45     for(int i=m;i>=1;i--){//处理回来的机票
46         if(a[i].t==0) continue ;
47         if(b[a[i].t]==-1) {
48             s++;b[a[i].t]=a[i].c;sum+=a[i].c;
49         }
50         else {
51             if(b[a[i].t]>a[i].c){
52                 sum-=b[a[i].t];
53                 sum+=a[i].c;
54                 b[a[i].t]=a[i].c;
55             }
56         }
57         if(s==n){
58             dp1[a[i].d]=sum;
59             y=max(y,a[i].d);
60         }
61     }
62   //cout<<dp1[8]<<" "<<dp1[9]<<" "<<dp1[15]<<endl;
63     for(int i=x+1;i<=1000000;i++) dp[i]=min(dp[i-1],dp[i]);
64     for(int i=y-1;i>=1;i--) dp1[i]=min(dp1[i+1],dp1[i]);
65 
66 
67     ll ans=INF;
68     for(int i=1;i<=1000000-k-1;i++){
69         if(dp[i]==INF||dp1[i+k+1]==INF) continue;
70         if(ans>dp[i]+dp1[i+k+1]){
71 
72             ans=dp[i]+dp1[i+k+1];
73         }
74 
75     }
76     if(ans==INF) cout<<-1<<endl;
77     else cout<<ans<<endl;
78 }
原文地址:https://www.cnblogs.com/hhxj/p/7491353.html