题目背景
kkksc03 的大学生活非常的颓废,平时根本不学习。但是,临近期末考试,他必须要开始抱佛脚,以求不挂科。
题目描述
这次期末考试,kkksc03 需要考 4 科。因此要开始刷习题集,每科都有一个习题集,分别有 s1,s2,s3,s4 道题目,完成每道题目需要一些时间,可能不等(A1,A2,…,As1,B1,B2,…,Bs2,C1,C2,…,Cs3,D1,D2,…,Ds4)。
kkksc03 有一个能力,他的左右两个大脑可以同时计算 22 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。
由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。
输入格式
本题包含 55 行数据:第 11 行,为四个正整数 s1,s2,s3,s4。
第 2 行,为 A1,A2,…,As1 共 s1个数,表示第一科习题集每道题目所消耗的时间。
第 3 行,为 B1,B2,…,Bs2 共 s2 个数。
第 4 行,为 C1,C2,…,Cs3 共 s3 个数。
第 5行,为 D1,D2,…,Ds4共 s4 个数,意思均同上。
输出格式
输出一行,为复习完毕最短时间。
输入数据 1
1 2 1 3
5
4 3
6
2 4 3
输出数据 1
20
首先看到这题,应该会发一会蒙?????
然后悲痛欲绝,开始骂老师为啥让做这么难的题!!!!!
最后认同开始做题……
良心发现做不出来TOT。。。。
摆烂inginginginginginginging#######
诚挚感谢可敬可爱的老师们,把写法讲了:)❀❀❀
这是一道极其不标准的搜索题(真出的一点也不水):
Ⅰ:由于kkksc03每次可以连续复习的科目都为同一个学科,所以搜索时要四个学科分别搜索一遍
Ⅱ:因为kkksc03每次最多可连续复习两科,所以我们可以将它看作左脑和右脑,再根据贪心思想发现左脑右脑工作量他到平衡时为最优解,所以就要让左脑和右脑的工作量无限接近一半这个值
Ⅲ:这样的话,思想雏形就有了,那要如何将他组建成搜索呢:
①首选深度优先搜索,将模板套用
②首先要找到遍历的层数,及结束边界设定,很明显是每科需复习的数量
③遍历内容大致为:1.在尽量保持平衡的情况下,找的与一半无限接近的值 不断刷新max
2.因为两边都要接近,只有小的一边尽量大,大的一边才能更小,min=大
推理总结:1.建模是两个大脑
2.想要保证所有都完成,就要取两个的大脑工作量的较大值
3.贪心思想可知,在两个大脑工作量相同时,较大值最小,为mid
4.那么就要想办法让大脑工作量无限接近这个值
5.一边大,另一边就会变小,所以耀荣小的尽量大,大的就会尽量小
这道题应用的大部分是贪心思想,推荐大家看一下解析,我就不在代码上写注释了
AC code:
#include <bits/stdc++.h>
using namespace std;
int nowtime,maxtime,sum,ans,maxdeep;
int s[5];
int a[25];
void dfs(int x)
{
if(x>maxdeep){
maxtime=max(maxtime,nowtime);
return;
}
if(nowtime+a[x]<=sum/2){
nowtime+=a[x];
dfs(x+1);
nowtime-=a[x];
}
dfs(x+1);
}
int main()
{
cin>>s[0]>>s[1]>>s[2]>>s[3];
for(int i=0;i<=3;i++){
nowtime=0;
maxdeep=s[i];
sum=0;
for(int j=1;j<=s[i];j++){
cin>>a[j];
sum+=a[j];
}
maxtime=0;
dfs(1);
ans+=(sum-maxtime);
}
cout<<ans;
return 0;
}