这题有点绕,我写了\(2h\)终于搞明白了。

主要思路:枚举最晚公布成绩的时间\(maxt\),然后将所有公布时间大于\(maxt\)的课程都严格降为\(maxt\)即可。

在此之前,还要搞清楚一个概念:对于第二种操作,它只有将某一门课提前,但是第一种操作,它还会在提前的过程中延迟某一门课。所以,在不考虑代价的情况下,选择第二种操作是更优也更快捷的。

接下来考虑分情况贪心。

  • 如果\(A \geq B\),说明第一种操作比第二种操作的代价来的高,操作也没有第二种优,所以肯定优先选择第二种操作。

  • 如果\(A<B\),说明第一种操作的代价比较小,所以可以先选第一种到不能选为止(已经没有课程可以延迟),剩余的再选第二种。

于是再算一下在最晚公布时间为\(i\)的情况下学生们的不愉快度即可。

实现过程

  • \(A \geq B\)的情况

此时我们要计算有多少门课公布的时间大于\(i\),我们可以先考虑将所有的课程按公布时间排序,然后把公布时间比\(i\)晚的课程先计算出来,这里我就用\(x\)来表示数量,则将这些课程公布的时间记作\(a_{m-x+1},a_{m-x+2}……a_m\)。

而我们的意图是将这里所有的值都化为\(i\),这其中经过的时间为\(a_{m-x+1}+a_{m-x+2}+……+a_m-i \times x\)

代价为\((a_{m-x+1}+a_{m-x+2}+……+a_m-i \times x) \times B\)

这个东西我们可以用前缀和\(O(1)\)的求出,而\(x\)的值怎么求可以参考我的代码。

  • \(A<B\)的情况

一样的,先算出要将其化为\(i\)需要经过的时间:

\(a_{m-x+1}+a_{m-x+2}+……+a_m-i \times x\) \((\)记作\(t1)\)

然后再算比\(i\)早公布时间的课程,我们可以将其延迟至\(i\)时间公布。

\(i \times (m-x) -(a_{1}+a_{2}+……+a_x)\) \((\)记作\(t2)\)

比较\(t1\)和\(t2\),如果\(t1 \leq t2\),说明可以全部用第一种操作搞定,代价为:\(t1 \times A\)

否则,剩余的再用第二种操作,代价为:\(t2 \times A+(t1-t2) \times B\)

  • 学生的不愉快度

考虑用一个\(Num\)记录在最晚公布时间为\(i\)的情况下不愉快的学生,将\(t_i\)从小到大排序,则不愉快的学生的等待时间记为:\(t_1,t_2,t_3……t_{Num}\)

总等待时间为:

\(i \times Num-(t_1+t_2+t_3……+t_{Num})\)

不愉快度为:

\((i \times Num-(t_1+t_2+t_3……+t_{Num})) \times C\)

那么最后注意一下用\(ull\),然后套柿子就没了。

\(Code:\)

  1. #include<bits/stdc++.h>
  2. #define long unsigned long long
  3. using namespace std;
  4. inline int read(){
  5. register int s=0,f=1;
  6. register char ch=getchar();
  7. while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}
  8. while(isdigit(ch))s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
  9. return s*f;
  10. }
  11. const int max_n=100000+5;
  12. long late[max_n],Time[max_n];
  13. long sum[max_n],f[max_n],num[max_n],h[max_n],maxt;
  14. long Max(long a,long b){
  15. if(a>b)return a;
  16. return b;
  17. }
  18. long Min(long a,long b){
  19. if(a<b)return a;
  20. return b;
  21. }
  22. int main(){
  23. ios::sync_with_stdio(false);
  24. long A=read(),B=read(),C=read();
  25. long n=read(),m=read();
  26. for(int i=1;i<=n;i++)late[i]=read();
  27. for(int i=1;i<=m;i++)Time[i]=read();//读入
  28. sort(Time+1,Time+m+1);//排序
  29. for(int i=1;i<=m;i++){
  30. maxt=max(maxt,Time[i]),sum[Time[i]]++;
  31. //找最晚公布的时间 //记录当前值,方便统计
  32. f[i]=f[i-1]+Time[i];//求前缀和
  33. }
  34. sort(late+1,late+n+1);//排序
  35. long Num=0;//不愉快的学生
  36. for(int i=1;i<=n;i++){
  37. num[late[i]]++,h[i]=h[i-1]+late[i];
  38. if(late[i]<=maxt)Num=i;
  39. }
  40. long ans=LONG_LONG_MAX;
  41. long x=0;//公布时间比i晚的课程
  42. for(int i=maxt;i>=1;i--){
  43. Num-=num[i];
  44. long tot=0;
  45. if(A>=B){
  46. long day=f[m]-f[m-x]-x*i;
  47. tot=Max(day*B,0);
  48. }else{
  49. long day1=f[m]-f[m-x]-x*i;
  50. long day2=(m-x)*i-f[m-x];
  51. if(day1<=day2)tot=Max(day1*A,0);
  52. else tot=Max(day2*A+(day1-day2)*B,0);
  53. }//贪心的核心部分,具体见分析,注意要严格保证不能为负数
  54. tot+=Max(Num*i-h[Num],0)*C;//加上学生的不愉快度
  55. x+=sum[i];//更新
  56. ans=Min(ans,tot);//取最小
  57. }
  58. cout<<ans<<endl;
  59. return 0;
  60. }

\(\operatorname{Update}\) \(\operatorname{On}\) \(\operatorname{2019.08.22}\)

题解 洛谷P3745 【[六省联考2017]期末考试】的更多相关文章

  1. 洛谷 P3745 [六省联考2017]期末考试

    题目描述 有 nnn 位同学,每位同学都参加了全部的 mmm 门课程的期末考试,都在焦急的等待成绩的公布. 第 iii 位同学希望在第 tit_iti​ 天或之前得知所有课程的成绩.如果在第 tit_ ...

  2. 洛谷P3745 [六省联考2017]期末考试

    传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...

  3. [luogu] P3745 [六省联考2017]期末考试 (贪心)

    P3745 [六省联考2017]期末考试 题目描述 有 \(n\) 位同学,每位同学都参加了全部的 \(m\) 门课程的期末考试,都在焦急的等待成绩的公布. 第 \(i\) 位同学希望在第 \(t_i ...

  4. 【BZOJ4868】[六省联考2017]期末考试(贪心)

    [BZOJ4868][六省联考2017]期末考试(贪心) 题面 BZOJ 洛谷 题解 显然最终的答案之和最后一个公布成绩的课程相关. 枚举最后一天的日期,那么维护一下前面有多少天可以向后移,后面总共需 ...

  5. 洛谷 P3747 [六省联考2017]相逢是问候 解题报告

    P3747 [六省联考2017]相逢是问候 题目描述 \(\text {Informatik verbindet dich und mich.}\) 信息将你我连结. \(B\) 君希望以维护一个长度 ...

  6. [BZOJ4868][六省联考2017]期末考试(三分)

    4868: [Shoi2017]期末考试 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 964  Solved: 439[Submit][Status ...

  7. 洛谷P3749 [六省联考2017]寿司餐厅

    传送门 题解 这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码. //Achen #include<algorithm> #include<iostream ...

  8. 洛谷 P3750 [六省联考2017]分手是祝愿

    传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...

  9. 洛谷P3747 [六省联考2017]相逢是问候

    传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream& ...

随机推荐

  1. 并行编程架构(指令流水、进程、线程、多核,Pipe and Filter)

    最近在进行DSP软件优化时,查阅文献,看到了几种并行机制,下面予以总结: 关键词一:指令流水 关键词二:多进程 关键词三:多线程 关键词四:多核(多处理器.超线程结构.多核结构.多核超线程架构) 在体 ...

  2. SpringBoot2+Druid+MyBatis+MySql实现增删改查

    1.配置pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  3. LeetCode 537. 复数乘法(Complex Number Multiplication)

    537. 复数乘法 537. Complex Number Multiplication 题目描述 Given two strings representing two complex numbers ...

  4. 使用flask做网页的excel成绩分析

    使用到的技术:pyecharts flask 首先 pip install flask 和下载pip install pyecharts==0.5.5 项目结构: 代码: from flask imp ...

  5. Java -- 最简单的认识重载

    定义 方法的名称相同,参数个数或类型不同的时候就成为方法重载. 示例 编写一个两个数相加的方法: public class hello{ public static void main(String ...

  6. AssemblyVersion、AssemblyFileVersion、AssemblyInformationalVersion 区别

    AssemblyVersion: 几乎保留在.NET内部,AssemblyFileVersion: 就是Windows所见.如果您转到位于目录中的程序集的属性并切换到版本选项卡, 映射到“文件版本”A ...

  7. 记录Quarter的基本使用

    原文:记录Quarter的基本使用 using Quartz; using Quartz.Impl; using Quartz.Impl.Matchers; using Quartz.Logging; ...

  8. Spring AOP创建AroundAdvice实例

    AroundAdvice 1.在方法之前和之后来执行相应的操作 2.实现MethodInterceptor接口 接口文件: public interface IHello { public void ...

  9. Python接口自动化基础---环境准备

    安装requests模块 pip install requests request帮助文档查看 import requests print(help(requests)) Help on packag ...

  10. Jenkins 构建方式有几种

    jenkins三种部署方式: 一.jenkins触发式构建:用于开发环境部署,开发人员push代码或者合并代码到gitlab项目的master分支,jenkins就部署代码到对应服务器. 二.jenk ...