【2018.4.5】Shoi2017题集
这三道题分别对应bzoj4868~4870,pdf没法往这放,因此放弃了。
T1:
方法1(正解):三分法
考虑暴力枚举最晚公布的时间x,关注到2操作是没有负面影响的1操作,所以如果A大于B,那么只需用2操作就可以了,否则先用1操作,不能用1操作后再用2操作。这样就能把b数组全部变成小于等于x,在加上额外的不愉快度就可以了。这个算法的时间复杂度是O(N2),可以拿60分。
如果你去打表就能发现不愉快度关于时间是一个下凸函数,可以用三分做。具体的证明是这样的:
1、修改代价关于时间是单调递减的,也就是说越晚出成绩修改代价越小;
2、额外代价关于时间是单调递增的,也就是说越晚出成绩额外代价越大;
3、最重要的一句,这两个函数的导数都是递增的。
感性的想一下,拿额外代价举例子,比如五个人的时间分别是1、2、2、3、3,时间从1改到2,需要额外代价的1个人(第一个人),但是从2改到3,需要额外代价的就变成了3个人,从3改到4所有的人都需要额外代价,也就是说刚开始额外代价增加慢,到后来额外代价增加快。
4、这样把这两个函数加起来,导数也是递增的,所以它是一个下凸函数(当然也有可能退化成单调函数)。
#include<cstdio>
#include<iostream>
#include<algorithm>
#define MN 100000
#define ll long long
using namespace std;
inline int read()
{
ll x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
} int n,m,t[MN+],s[MN+];
ll A,B,C,ans=1e18; ll calc(int tms)
{
ll sum=,left=,need=;
for(int i=;i<=n;++i) sum+=C*max(,tms-t[i]);
for(int i=;i<=m;++i)
if(s[i]>tms) need+=s[i]-tms;
else left+=tms-s[i];
if(B<A)return sum+need*B;
else if(left>=need) return sum+need*A;
else return sum+left*A+(need-left)*B;
} void Solve(int l,int r)
{
if(r-l<=)
{
for(int i=l;i<=r;++i) ans=min(ans,calc(i));
return;
}
int m1=(r-l+)/+l,m2=(r-l+)/*+l;
if(calc(m1)<calc(m2)) Solve(l,m2-);
else Solve(m1+,r);
} int main()
{
A=read();B=read();C=read();
n=read();m=read();int mx=;
for(int i=;i<=n;++i) mx=max(mx,(t[i]=read()));
for(int i=;i<=m;++i) mx=max(mx,(s[i]=read()));
Solve(,mx);
printf("%lld\n",ans);
return ;
}
T1-1
注意到有两个数据C=1016,如果考试现场写的时候怕爆炸,可以特判一下用足够的1、2操作让每个学生都不等待,因为这种情况只要有一个学生等待答案就不是最优。
三分法的时间复杂度……根据 T(n)=T(2n/3)+O(n) 可以知道复杂度大概是O(2n log3 n),比O(n log2 n)(二分)慢了不少,但好歹也是log级别的。
方法2:枚举DDL
直接枚举Deadline(最晚成绩公布时间),时间复杂度O(n)......
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define MAXN 100005
#define INF 1e16
typedef long long LL;
using namespace std;
int n,m,a,b,c;
LL student[MAXN],course[MAXN];
int read()
{
int x=;char c=getchar();
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')x=x*+c-'',c=getchar();
return x;
}
int main()
{
a=read(),b=read(),c=read(),n=read(),m=read();
int day=;LL cost=,mov=,left=,ans;
for(int i=;i<=n;i++)
{int t;t=read();student[t]++;day=max(day,t);}
for(int i=;i<=m;i++)
{int t;t=read();course[t]++;day=max(day,t);}
for(int i=;i<=day;i++)
{
cost+=student[i]*(day-i);
left+=course[i]*(day-i);
student[i]+=student[i-];//维护前缀和
course[i]+=course[i-];
}
ans=cost*c;
for(int i=day-;i>;i--)
{
mov+=(m-course[i]);//在这天后完结的课需要向前移动一天
left-=course[i];//前面的所有课程向后移动的范围减少了1天
cost-=student[i];//减掉希望在这天以前完结的学生一天的不满意度
if(c>=INF&&cost)continue;
LL p=left>?left:;
if(mov<p)p=mov;
if(a<b)ans=min(ans,p*a+(mov-p)*b+cost*c);
else ans=min(ans,mov*b+cost*c);
}
printf("%lld\n",ans);
return ;
}
T1-2
T2:
数学题ToT,和bzoj3884的坑爹程度有些相似。
【2018.4.5】Shoi2017题集的更多相关文章
- ACM题集以及各种总结大全!
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...
- 全国各大 oj 分类题集...
各种题集从易到难刷到手软 你准备好了吗? 准备剁手吧
- ACM题集以及各种总结大全(转)
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...
- 组合数取模&&Lucas定理题集
题集链接: https://cn.vjudge.net/contest/231988 解题之前请先了解组合数取模和Lucas定理 A : FZU-2020 输出组合数C(n, m) mod p (1 ...
- Bug是一种财富-------研发同学的错题集、测试同学的遗漏用例集
此文已由作者王晓明授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 各位看官,可能看到标题的你一定认为这是一篇涉嫌"炒作"的文章,亦或是为了吸引眼球而起的标 ...
- 数位dp题集
题集见大佬博客 不要62 入门题,检验刚才自己有没有看懂 注意一些细节. 的确挺套路的 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...
- UOJ#428. 【集训队作业2018】普通的计数题
#428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...
- 二级C语言题集
时间:2015-5-13 18:01 在131题之后是按考点分类的题集,有需要的朋友可以看一下 ---------------------------------------------------- ...
- 中南大学2018年ACM暑期集训前期训练题集(入门题) X: 又一道简单题
简直智障,上一题V题,样例输出里面的“Case:”不要输出,到了这题又是要输出的了 #include<iostream> using namespace std; int num[1000 ...
随机推荐
- CodeForces 219D Choosing Capital for Treeland (树形DP)
题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少.并输出所有可能作为根的点. 思路: 先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用 ...
- crontab 应用
可以用crontab -e 添加要执行的命令. 命令执行的结果,无论是标准输出还是错误输出,都将以邮件形式发给用户. 添加的命令必须以如下格式: * * * * * /co ...
- git 添加 ,密匙
转载此处 https://blog.csdn.net/xiayiye5/article/details/79652296
- 关于highchts X时间轴比设置时间相差好几个小时的解决
经过一番查询和研究发现,在曲线图里,x轴的UNIX时间戳是要乘以1000的(通过在线的UNIX转换,结果与原来没有乘以1000的时间戳相差甚远),不然显示的时间会有很大的误差,真是百思不得其解. 另外 ...
- ubuntu 18.* 重启网卡
systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active waiting A ...
- PAT (Advanced Level) Practise - 1097. Deduplication on a Linked List (25)
http://www.patest.cn/contests/pat-a-practise/1097 Given a singly linked list L with integer keys, yo ...
- Authentication token manipulation error报错解决办法
Authentication token manipulation error报错解决办法 #参考http://blog.163.com/junwu_lb/blog/static/1916798920 ...
- jquery 获取tbody下的第二个tr 及多级标签
<div id="testSlider"> <div class="esriTimeSlider ies-Slider" id="t ...
- LeetCode 买卖股票的最佳时机 II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必须在再次 ...
- windows显示文件扩展名
搜索打开windows的文件资源管理选项,如下去掉“隐藏已知文件类型的扩展名”即可 打开之后显示如下: