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;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网技术栈

领域驱动模型(DDD)

2004年Eric Evans 发表《领域驱动设计——软件核心复杂性应对之道》(Domain-Driven Design –Tackling Complexit...

2641
来自专栏无原型不设计

UI / UX设计师如何玩转用户心理学原理?

以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具。 ? 众所周知,心理学在APP的用户体验设计中起着非常...

3357
来自专栏余林丰

桥接模式

桥接模式要把握的很重要的一点就是:类的继承关系和类的组合/聚合关系,何时应该考虑使用何种关系。是不是在编程过程中一味地使用类的继承关系就代表这就是面向对象编程了...

2207
来自专栏企鹅号快讯

争论背后的编程语言:谁最容易出bug?

【IT168 评论】10月份,ACM发布了一个关于编程语言对软件质量的影响的研究报告,在报告中有一些关于bug的有趣发现。 研究人员Baishakhi Ray,...

2316
来自专栏Java社区

做一个网站真的有那么难吗?

1383
来自专栏GopherCoder

『No24: 编写可读代码的艺术(1)』

除了本职工作,还有点幻灯片演示设计的爱好。随着编写代码的增多,制作的的幻灯片越来越多,越来越意识到,很多事物都存在相通性。

982
来自专栏Vamei实验室

Python快速教程 尾声

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

1342
来自专栏博客园

设计模式学习---策略模式

最近在看"Head First 设计模式"这本书,便想将自己所学的记录下来以加深理解,文中肯定有许多不足之处,请各位前辈们指出.

1054
来自专栏PPV课数据科学社区

为什么要选择Python语言实现机器学习算法

点击上方 “蓝色字” 可关注我们! 我们选择Python作为实现机器学习算法的编程语言:(1) Python的语法清晰;(2) 易于操作纯文本文件;(3) 使用...

3768
来自专栏PPV课数据科学社区

对5种主流编程语言的吐槽

接下来要为大家,介绍五款让我又爱又恨的编程语言! 不可否认,想要成为一名优秀的程序员确实是需要掌握多种编程语言。通过这几年的自虐式学习,我也慢慢的掌握了这些编程...

52810

扫码关注云+社区

领取腾讯云代金券