cf 853 B Jury Meeting [前缀和]

题面:

传送门

思路:

看完题目以后,首先有一个结论:每个人都是先去到首都,等待开会,开会结束以后再一个个走掉

而且这道题只有去首都和离开首都的机场

因此考虑计算去首都的飞机的前缀最小花费,以及离开首都的飞机的最小后缀花费

都计算出来以后,对于每一个开始开会的时间t,用pre[t-1]+suf[t+k]来更新答案即可

Code:

到处都要用long long......

最后我只好ctrl+R,替换int为longlong了......

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define ll long long
 6 const ll inf=1e15;
 7 using namespace std;
 8 inline ll read(){
 9     ll re=0,flag=1;char ch=getchar();
10     while(ch>‘9‘||ch<‘0‘){
11         if(ch==‘-‘) flag=-1;
12         ch=getchar();
13     }
14     while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar();
15     return re*flag;
16 }
17 ll n,m,K,cnta,cntb,cntva,cntvb;
18 ll pre[2000010],suf[2000010];ll suma,sumb;
19 bool vis[100010];ll minn[100010];
20 struct flight{
21     ll to,cost,t;
22 }a[100010],b[100010];
23 bool cmp(flight l,flight r){
24     return l.t<r.t;
25 }
26 bool cmp2(flight l,flight r){
27     return l.t>r.t;
28 }
29 int main(){
30     ll i,j,t1,t2,t3,t4;ll ans=inf;
31     n=read();m=read();K=read();
32     for(i=1;i<=m;i++){
33         t1=read();t2=read();t3=read();t4=read();
34         if(t2!=0) a[++cnta]=(flight){t2,t4,t1};
35         else b[++cntb]=(flight){t3,t4,t1};
36     }
37     if(cnta<n||cntb<n){
38         puts("-1");return 0;
39     }
40     sort(a+1,a+cnta+1,cmp);sort(b+1,b+cntb+1,cmp2);
41     for(i=1;i<=n;i++) suma+=(ll)(minn[i]=inf);
42     t1=1;pre[1]=inf;
43     for(i=1;i<=cnta;i++){
44         for(j=t1+1;j<a[i].t;j++) pre[j]=pre[j-1];
45         t1=a[i].t;
46         if(!vis[a[i].to]) vis[a[i].to]=1,cntva++;
47         suma-=minn[a[i].to]-min(minn[a[i].to],a[i].cost);
48         minn[a[i].to]=min(minn[a[i].to],a[i].cost);
49         if(cntva==n) pre[t1]=suma;
50         else pre[t1]=-1;
51     }
52     memset(vis,0,sizeof(vis));
53     for(i=1;i<=n;i++) sumb+=(ll)(minn[i]=inf);
54     t1=2000005;suf[t1]=inf;
55     for(i=1;i<=cntb;i++){
56         for(j=t1-1;j>b[i].t;j--) suf[j]=suf[j+1];
57         t1=b[i].t;
58         if(!vis[b[i].to]) vis[b[i].to]=1,cntvb++;
59         sumb-=minn[b[i].to]-min(minn[b[i].to],b[i].cost);
60         minn[b[i].to]=min(minn[b[i].to],b[i].cost);
61 //        cout<<"calc "<<i<<ends<<t1<<ends<<cntvb<<ends<<sumb<<endl;
62         if(cntvb==n) suf[t1]=sumb;
63         else suf[t1]=-1;
64     }
65 //    for(i=1;i<=20;i++) cout<<suf[i]<<endl;
66     t1--;while(t1) suf[t1]=suf[t1+1],t1--;
67 //    for(i=1;i<=20;i++) cout<<suf[i]<<endl;
68 //    for(i=1;i<=20;i++) cout<<pre[i]<<endl;
69     for(i=1;i<=cnta;i++){
70         t1=a[i].t;t2=t1+K+1;
71         if(~pre[t1]&&~suf[t2]) ans=min(ans,(ll)pre[t1]+(ll)suf[t2]);
72     }
73     if(ans>=inf) printf("-1");
74     else printf("%I64d\n",ans);
75 }

原文地址:https://www.cnblogs.com/dedicatus545/p/8453805.html

时间: 2024-10-03 18:17:50

cf 853 B Jury Meeting [前缀和]的相关文章

CF Round433 B. Jury Meeting

题目链接:http://codeforces.com/problemset/problem/853/B 题目大意:自己看吧... 解题思路:刚开始看题解也没看明白,搞了一下午.最后一句话给看到一句话: 排序后前缀最小花费,后缀最小花费,扫一遍就OK了. 具体过程:按照day排序之后,记录前缀最小花费以及对应的最大day,记录后缀最小花费以及对应最小day,然后用双指针对前缀的每一个查找后缀中满足条件的,更新ans即可. 对于前缀,如果j > i, 则 prefix(j) <= prefix(i

Jury Meeting CodeForces - 854D

Jury Meeting CodeForces - 854D 思路:暴力枚举会议开始的那一天(只需用所有向0点飞的航班的那一天+1去枚举即可),并计算所有人此情况下去0点和从0点出来的最小花费. 具体:首先,将航班分为飞入0和飞出0两类. 然后,枚举会议开始的时间p. 那么,飞入0的航班只有时间<p的生效,飞出0的航班只有时间>p+k-1的生效. 显然,在p变为p+1时,最多只有各一班航班生效与失效. (听说还能二分,但是已经打了100行了,不敢再加了...好累) 1 #include<

Jury Meeting CodeForces - 854D (前缀和维护)

Country of Metropolia is holding Olympiad of Metrpolises soon. It mean that all jury members of the olympiad should meet together in Metropolis (the capital of the country) for the problem preparation process. There are n + 1 cities consecutively num

CF F. Shovels Shop(前缀和预处理+贪心+dp)

F. Shovels Shop time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output There are nn shovels in the nearby shop. The ii -th shovel costs aiai bourles. Misha has to buy exactly kk shovels. Each sho

Codeforces 853B Jury Meeting

题意 从城市1-n来的评审团到城市0商讨国家大事,离开和抵达的那一天不能讨论,飞机均当天抵达,给出所有飞机起飞抵达代价情况,问能否使所有评审员聚齐连续k天并返回,并求最小代价 思路 从前向后扫一遍,求每天的出发最小代价L[i],从后向前扫,求每天最小离开代价R[i] 从前向后扫一遍,每天的最小代价为L[i]+R[i+k+1] 将每天的默认大小设为1e12,因为最大代价不超过1e11,可以据此确定答案是否合法 代码 #include<bits/stdc++.h> using namespace

cf 853 A planning [贪心]

题面: 传送门 思路: 一眼看得,这是贪心[雾] 实际上,我们要求的答案就是sigma(ci*(ti-i))(i=1~n),这其中sigma(ci*i)是确定的 那么我们就要最小化sigma(ci*ti) 所以在新的每一秒,就把这一秒开始可以起飞的飞机中,cost最大的那一个拿出来,让他起飞就可以了 证明: 设最大的为m,我们取得另一个为n 那么n*ti+m*(ti+1) >= n*(ti+1)+m*ti 所以取m最好 这个过程用堆实现,懒得手打了,就用了priority_queue Code:

cf 853 D Michael and Charging Stations [dp]

题面: 传送门 思路: 看到题目,第一思路是贪心,但是我很快就否决掉了(其实分类贪心也可以做) 然后就想,贪心不能解决的状态缺失,是否可以用dp来解决呢? 事实证明是可以的 我们设dp[i][j]表示第i天,还剩j*100积分的时候,最小花费的现金 有转移:dp[i][j]=min(dp[i-1][k]+cost[i]-(k-j)*100)(k=j+1...min(30,j+cost[i]/100) 最后再dp[i][j]=min(dp[i][j],dp[i-1][j-cost[i]/1000]

Codeforces Round #433 (Div. 2)

题目链接:Codeforces Round #433 (Div. 2) codeforces 854 A. Fraction[水] 题意:已知分子与分母的和,求分子小于分母的 最大的最简分数. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int gcd(int a,int b){re

差分简单题集

[一维差分]Codeforces 1000C Covered Points Count 题目大意: 给定$n$个线段,给定这些线段所在的区间($l,r\leq10^{18}$),这些线段能够覆盖它们所包含的点,问你被包含$[1,n]$次的点分别有多少个. 解题分析:用差分来高效的统计一下指定区间内所被覆盖的线段个数,同时,因为$l,r$的大小非常大,所以我们需要对所有的线段进行离散化. #include <bits/stdc++.h> using namespace std; template