• 三分 BZOJ4868 [Sxoi2017] 期末考试


    4868: [Sxoi2017]期末考试

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 605  Solved: 270
    [Submit][Status][Discuss]

    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

    黑吉辽沪冀晋六省联考

    通过枚举多组样例和数学直觉,可以意识到题目中不愉快度之和是一个下凸函数,那么可以用三分。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 long long a,b,c,mn;
     7 int n,m; 
     8 long long ti[100010],bi[100010];
     9 long long judge(long long x){
    10     long long ret=0;
    11     if(a<b){
    12         long long tmp1=0,tmp2=0;
    13         for(int i=1;i<=m;i++)
    14             if(x<bi[i]) tmp1+=bi[i]-x;
    15             else if(x>bi[i]) tmp2+=x-bi[i];
    16         if(tmp2>=tmp1) ret+=tmp1*a;
    17         else ret+=tmp2*a+(tmp1-tmp2)*b; 
    18     } 
    19     else for(int i=1;i<=m;i++)
    20             if(x<bi[i]) ret+=(bi[i]-x)*b;
    21     for(int i=1;i<=n;i++)
    22         if(x>ti[i]) ret+=(x-ti[i])*c;
    23     return ret;
    24 }
    25 long long solve(){
    26     long long ll=1,rr=100000;
    27     while(ll+2<rr){
    28         long long mid1=(2*ll+rr)/3,mid2=(ll+2*rr)/3;
    29         long long t1=judge(mid1),t2=judge(mid2);
    30         if(t1==t2) ll=mid1,rr=mid2;
    31         else if(t1<t2) rr=mid2;
    32             else ll=mid1; 
    33     }
    34     long long t1=judge(ll),t2=judge(rr),t3=judge((2*ll+rr)/3),t4=judge((ll+2*rr)/3);
    35     return min(min(t1,t2),min(t3,t4));
    36 }
    37 int main(){
    38     scanf("%lld%lld%lld",&a,&b,&c);
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=n;i++) scanf("%lld",&ti[i]);
    41     for(int i=1;i<=m;i++) scanf("%lld",&bi[i]);
    42     if(c==1e16){
    43         mn=1e20;
    44         for(int i=1;i<=n;i++) mn=min(mn,ti[i]);
    45         printf("%lld
    ",judge(mn));
    46         return 0;   
    47     }
    48     printf("%lld
    ",solve());
    49     return 0;
    50 } 

    sdfzyhx有一种线性的算法,通过枚举结束的时间,借助前缀和和后缀和,但我并不太懂……贴个链接

  • 相关阅读:
    JeePlus:代码生成器
    JeePlus:API工具
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
  • 原文地址:https://www.cnblogs.com/zwube/p/7259840.html
Copyright © 2020-2023  润新知