BZOJ4868: [Shoi2017]期末考试
Description
有n位同学,每位同学都参加了全部的m门课程的期末考试,都在焦急的等待成绩的公布。第i位同学希望在第ti天
或之前得知所.有.课程的成绩。如果在第ti天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程
公布成绩,每等待一天就会产生C不愉快度。对于第i门课程,按照原本的计划,会在第bi天公布成绩。有如下两种
操作可以调整公布成绩的时间:1.将负责课程X的部分老师调整到课程Y,调整之后公布课程X成绩的时间推迟一天
,公布课程Y成绩的时间提前一天;每次操作产生A不愉快度。2.增加一部分老师负责学科Z,这将导致学科Z的出成
绩时间提前一天;每次操作产生B不愉快度。上面两种操作中的参数X,Y,Z均可任意指定,每种操作均可以执行多次
,每次执行时都可以重新指定参数。现在希望你通过合理的操作,使得最后总的不愉快度之和最小,输出最小的不
愉快度之和即可
Input
第一行三个非负整数A,B,C,描述三种不愉快度,详见【问题描述】;
第二行两个正整数n,m(1≤n,m≤105),分别表示学生的数量和课程的数量;
第三行n个正整数ti,表示每个学生希望的公布成绩的时间;
第四行m个正整数bi,表示按照原本的计划,每门课程公布成绩的时间。
1<=N,M,Ti,Bi<=100000,0<=A,B,C<=100000
Output
输出一行一个整数,表示最小的不愉快度之和。
Sample Input
100 100 2 4 5 5 1 2 3 1 1 2 3 3
Sample Output
6 由于调整操作产生的不愉快度太大,所以在本例中最好的方案是不进行调整; 全部 5 的门课程中,最慢的在第 3 天出成绩; 同学 1 希望在第 5 天或之前出成绩,所以不会产生不愉快度; 同学 2 希望在第 1 天或之前出成绩,产生的不愉快度为 (3 - 1) * 2 = 4; 同学 3 希望在第 2 天或之前出成绩,产生的不愉快度为 (3 - 2) * 2 = 2; 同学 4 希望在第 3 天或之前出成绩,所以不会产生不愉快度; 不愉快度之和为 4 + 2 = 6 。
HINT
存在几组数据,使得C = 10 ^ 16
Source
考场上还是静不下心来
总感觉这题是个dp
然后直接弃掉了。
其实还是挺简单的。
我们钦定一个试卷被批完的最晚时间
然后通过二分+前缀和计算出学生的不愉快度
再利用二分+后缀和计算出让最后一个被批完的试卷的时间满足要求的不愉快的
两者求和取最小值就可以了
这道题的关键是看出学生不满意度和试卷被批完的时间之间的单调关系
然后要想到枚举时间
#include<cstdio>
#include<cmath>
#include<algorithm>
#define int unsigned long long
using namespace std;
const int MAXN=1e5+10;
const int INF=1e19;
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int A,B,C;
int N,M;
int t[MAXN],b[MAXN];
int sumt[MAXN],sumb[MAXN];//t的前缀与b的后缀
int limit,ans=INF;
main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#endif
A=read();B=read();C=read();
N=read();M=read();
for(int i=1;i<=N;i++) t[i]=read();
for(int i=1;i<=M;i++) b[i]=read(),limit=max(limit,b[i]);
sort(t+1,t+N+1);
sort(b+1,b+M+1);
for(int i=1;i<=N;i++) sumt[i]=t[i]+sumt[i-1];
for(int i=M;i>=1;i--) sumb[i]=b[i]+sumb[i+1];
for(int i=1;i<=limit;i++)
{
int l=1,r=N,ans1=0,ans2=0,now=0;
while(l<=r)
{
int mid=l+r>>1;
if(t[mid]<i) ans1=mid,l=mid+1;
else r=mid-1;
}
l=1,r=M;
while(l<=r)
{
int mid=l+r>>1;
if(b[mid]>i)
ans2=mid,r=mid-1;
else l=mid+1;
}
if(ans1!=0) now+=(ans1*i-sumt[ans1])*C;
if(ans2!=0)
{
int need=(sumb[ans2]-(M-ans2+1)*i);
if(A>=B) now+=need*B;
else
{
int have=(ans2-1)*i-(sumb[1]-sumb[ans2]);
if(have>=need) now+=need*A;
else now+=have*A+(need-have)*B;
}
}
ans=min(ans,now);
}
printf("%lld",ans);
return 0;
}
- 机器学习中常用评估指标汇总
- 用 Grid Search 对 SVM 进行调参
- PCA 的数学原理和可视化效果
- 用 Pipeline 将训练集参数重复应用到测试集
- 什么是 ROC AUC
- SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用
- 详解 Stacking 的 python 实现
- RESTful接口设计原则和优点
- 用 Doc2Vec 得到文档/段落/句子的向量表达
- 手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
- 项目中记录影响性能的缓慢数据库查询
- memory_profiler的使用
- 使用line_profiler查看api接口函数每行代码执行时间
- GAN 的 keras 实现
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 10行python代码制作笑死人不偿命的倒放gif
- “Hello Node.js” 这一次是你没见过的写法
- 作为DBA,你不得不掌握的压测工具
- Mac之vim普通命令使用
- selenium库的基本使用
- 高效大数据开发之 bitmap 思想的应用
- 从0到1实现一个虚拟DOM
- Xenomai XDDP example and Posix Compling
- 项目实践|基于Flink的用户行为日志分析系统
- 手把手教你用Matplotlib画一个小清新配色的商业图表
- 高并发场景下锁的使用技巧
- Struts2第四天:Struts2的拦截器和标签库
- kubernete编排技术八:使用operator管理有状态应用
- Spring第一天:Spring的概述、SpringIOC入门(XML)、Spring的Bean管理、Spring属性注入
- Flink的处理背压原理及问题-面试必备