tyvj 2017.9.17 test P4867 天天寄快递(暴力)
额 第二天的模拟赛吃鸡去了所以没参加
历时两天把这道day2 t1做了
感谢xd大佬博客的启发
天天寄快递
express.in/.out/.cpp
【问题描述】
天天暑假时帮别⼈寄送快递,经历了⼀个暑假,天天积累了不少数据, 想对快递公司进⾏⼀下评分,得到快递公司的质量⽔平。 总共有 n 家快递公司,编号为 1..n。现在天天有 m 天的寄送快递数据, 其中第 i 天使⽤第 ei 家快递公司,快递在路上花了 ti 天时间。⼀开始每个 快递公司的评分都为 0,对于⼀家快递公司,如果⼀个包裹花了 ti 天寄到, 那么对这家快递公司的评分贡献为 2−ti,(如果花的时间超过两天得分就会 变成负的啦)。 然⽽事情没有这么简单,如果某⼀天的数据丢掉了,天天为了公平起见 就忽略掉这天的数据。于是快递公司联盟决定雇佣⼀个⼩偷,⼩偷可以偷⾛ 最多 s 天的数据,使得每个公司的信⽤得分⾄少增加 k,且所有快递公司的 信⽤总和尽量⼤。 若如果被偷以后,⽆法让每个公司的信⽤得分都⾄少增加 k,输出 −23333333,否则请你输出被偷后, 所有快递公司的信⽤得分的和最多增 加多少。
【输入格式】 第⼀⾏四个整数 n,m,s,k,其中 1 ≤ n,m ≤ 100,000,0 ≤ s ≤ m,0 ≤ k ≤ 109。 接下来 m ⾏,每⾏两个整数。接下来的第 i ⾏为 ei,ti,其中 1 ≤ ei ≤ n,0 ≤ ti ≤ 109。
【输出格式】
⼀个整数,为题⽬要求的答案。
2
【样例输入】
2 5 4 22 1 1 1 40 2 25 2 30 2 0
【样例输出】
89
【样例解释】
⼩偷可以偷 4 天的数据,但是⼩偷实际上只偷了第 2,3,4 天的数据,1 号公司获得了 38 分的提升,2 号公司获得了 23 + 28 分的提升,都满⾜了 最⼩提升 22 分的要求。
【数据规模和约定】 对于 30% 的数据,1 ≤ n,m ≤ 20。 对于 100% 的数据,1 ≤ n,m ≤ 200,000,。
这道题就是暴力,排序之后去掉负值然后算就行了
代码如下:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<cmath> #include<vector> #define ll long long #define f(i,l,r) for(int i = l;i <= r;i++) using namespace std; const int maxn = 200005; inline void read(int &x){ //快读 int f = 1;x = 0;char ch; do{ch = getchar();if(ch == '-') f = -1;} while(ch < '0' || ch > '9'); do{ x = x * 10 + ch - '0'; ch =getchar(); } while(ch >= '0' && ch <= '9'); x*=f; } struct xd{ int e,t; }a[maxn]; int n,m,s,k,f = 0,now[maxn]; bool flag[maxn]; int cmp(xd a,xd b){ //排序 return a.t < b.t; } int main(){ read(n);read(m);read(s);read(k); f(i,1,m){ //读入 read(a[i].e);read(a[i].t); a[i].t = 2 - a[i].t; } sort(a+1,a+m+1,cmp); f(i,1,m){ if(a[i].t > 0) break; //当有大于0的时候跳出 if(now[a[i].e] < k){ //处理 now[a[i].e] -= a[i].t; flag[i] = 1; //标记当前的已经不需要加 f++; //天数加一 } } if(f > s){ //所用天大于需要天就不行 printf("-23333333\n"); return 0; } f(i,1,n){ //有小于所需的值就不行 if(now[i] < k){ printf("-23333333\n"); return 0; } } if(f != s) f(i,1,m){ //没什么好说的就是处理没处理过的数据 if(flag[i] == 1) continue; if(a[i].t > 0 || f == s) break; //达成条件跳出循环 now[a[i].e] -= a[i].t; f++; } long long ans = 0; //不开long long只有30分 f(i,1,n){ ans += now[i]; } cout<<ans<<endl; return 0; }