洛谷题目链接:切蛋糕

题目描述

Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴。他答应给每个人留一口,然后量了量每个人口的大小。Facer有把刀,可以切蛋糕,但他不能把两块蛋糕拼起来,但是他又不会给任何人两块蛋糕。现在问你,facer怎样切蛋糕,才能满足最多的人。(facer的刀很强,切的时候不会浪费蛋糕)。

输入输出格式

输入格式:

第一行n,facer有n个蛋糕。接下来n行,每行表示一个蛋糕的大小。再一行一个数m,为信息组的人数,然后m行,每行一个数,为一个人嘴的大小。(1<=n<=50, 1<=m<=1024)

输出格式:

一行,facer最多可以填多少张嘴巴。

输入输出样例

输入样例#1:

4

30

40

50

25

10

15

16

17

18

19

20

21

25

24

30

输出样例#1:

7

简述一下题意:给出\(n\)块蛋糕的大小和\(m\)个人要吃的量.现在只允许切蛋糕,求最多能满足多少人的需求.




我们并不知道最终能满足多少人,但是很显然,肯定要优先满足需求较小的人.所以可以现将每个人的需求排个序,这样口的大小的数组就是单调的了.既然是单调的,就可以用二分来确定最多能否满足前mid个人.前mid个人能否满足直接爆搜就可以了.




然而,这样并过不了,因为数据范围,这么搞是肯定要TLE的.所以我们可以考虑一下剪枝.

  • 因为口的大小是单调的,所以如果第\(i\)个人和第\(i-1\)个人的口大小相同,不能满足第\(i\)个人就不能满足第\(i-1\)个人.
  • 因为每次切都会有浪费(搜索过程中并不知道哪些一定可以作为浪费,但是如果第一个人都无法满足就一定是浪费了的),所以可以吧浪费的统计下来,那么如果蛋糕的总和减去浪费的总量小于前\(mid\)个人的口的大小,则不论怎么搜,都搜不出结果.
  • 然后就是在搜索的过程中可以先从第\(mid\)个开始往第一个搜,因为能满足第\(mid\)人的情况比较少,可以减少分支.
#include<bits/stdc++.h>
using namespace std;
const int N=50+5;
const int M=1024+5; int n, m, ans = 0, waste = 0;
int cake[N], temp[N], sum = 0;
int mouth[M], pre[M]; bool dfs(int person,int pos,int mid){
if(person == 0) return true;
if(sum-waste < pre[mid]) return false;
for(int i=pos;i<=n;i++){
if(temp[i] < mouth[person]) continue;
temp[i] -= mouth[person];
if(temp[i] < mouth[1]) waste += temp[i];
if(mouth[person] == mouth[person-1]){
if(dfs(person-1,i,mid)) return true;
}
else if(dfs(person-1,1,mid)) return true;
if(temp[i] < mouth[1]) waste -= temp[i];
temp[i] += mouth[person];
}
return false;
} bool check(int mid){
memcpy(temp,cake,sizeof(temp));
waste = 0; bool res = dfs(mid,1,mid);
if(res) return true;
return false;
} int main(){
//freopen("data.in","r",stdin);
cin >> n;
for(int i=1;i<=n;i++) cin >> cake[i], sum += cake[i];
cin >> m;
for(int i=1;i<=m;i++) cin >> mouth[i];
sort(mouth+1 , mouth+m+1); sort(cake+1 , cake+n+1);
for(int i=1;i<=m;i++) pre[i] = pre[i-1]+mouth[i];
int l = 0, r = m, mid;
while(pre[r] > sum) r--;
while(l <= r){
mid = (l+r>>1);
if(check(mid)) l = mid+1, ans = mid;
else r = mid-1;
}
printf("%d\n",ans);
return 0;
}

[洛谷P1528] 切蛋糕的更多相关文章

  1. 洛谷P1528 切蛋糕 [搜索,二分答案]

    题目传送门 切蛋糕 题目描述 Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴.他答应给每个人留一口,然后量了量每个人口的大小.Facer有把刀 ...

  2. 【算法•日更•第六期】头脑风暴:洛谷P1528 切蛋糕题解

    ▎(一个没有用处的)前言 为什么这次题解特意写明题号呢?因为我发现了这样的事情: 所以不要混了,想看P1714题解的同志们可以圆润的滚开了. 好了,不说没用的了,切入正题: ▎题目 题目及测评链接:戳 ...

  3. 洛谷 P1714 切蛋糕 题解

    P1714 切蛋糕 题目描述 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运 ...

  4. 洛谷 P1714 切蛋糕 单调队列

    这个题比较显然,要用前缀和来做.但只用前缀和是过不去的,会TLE,所以需要进行优化. 对于每个前缀和数组 b 中的元素,都可以找到以 b[i] 结尾的子段最大值 p[i],显然,最终的 ans 就是 ...

  5. 洛谷—— P1714 切蛋糕

    https://www.luogu.org/problem/show?pid=1714 题目描述 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每 ...

  6. [洛谷P1714]切蛋糕

    题目大意:给你n个整数,求出其中长度不超过m的最大字段和. 题解:单调队列维护前缀和最小值,然后用当前值减去当前有效最小值即可 C++ Code: #include<cstdio> usi ...

  7. 洛谷P1714切蛋糕

    题目 该题目就是求这n个数的前缀和所组成的数组的所有子区间的左端点和右端点相差不超过m,且他们的前缀和差最大,求出这个最大值即可. 而朴素算法肯定会T,而我们发现如果前缀和最大的话,则前缀和的值一定是 ...

  8. 洛谷P1714 切蛋糕(单调队列)

    先放代码...... 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=5e5+10,M=0x3f3f3f3f; ...

  9. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

随机推荐

  1. 【Consul】Consul架构-Gossip协议

    Consul使用gossip协议管理成员关系.广播消息到整个集群.详情可参考Serf library,Serf使用到的gossip协议可以参阅"SWIM: Scalable Weakly-c ...

  2. CentOS修改网卡名称

    转 一.问题说明 测试环境中出现的小问题,因为虚拟机之间经常复制来复制去,导致网卡配置这块的不一致现象. 配置文件的信息: [root@ora10g network-scripts]# catifcf ...

  3. Messy Code in Windows Server 2008 R2 English Edition

          We always use Windows Server 2008 R2 English operation system. And it doesn't have any problem ...

  4. mybatis <collection>标签 类型为string时无法获取重复数据错误

    1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...

  5. CPU拓扑结构

    本篇旨在认识一下以下三种CPU拓扑结构分别是什么: Symmetric multiprocessing (SMP) Non-uniform memory access (NUMA) Simultane ...

  6. C语言运算符(注意事项)

    1.C语言取余注意事项:%   a.求余.模运算符(%)时要求两数必须是整型数据. b.取余的结果,是取决于被除数   (不管除数是正数 还是 负数,模的符号与被除数的符号相同).   例:8÷2=4 ...

  7. HDU 4722 Good Numbers(位数DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description If we sum up every digit of a number and the result can be exactly divided by 10, we say ...

  8. Python模块学习:logging 日志记录

    原文出处: DarkBull    许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪.在.NET平台中,有非常著名的第三方开源日志组件log4net ...

  9. 软工实践Beta冲刺(7/7)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...

  10. PS制作圆角透明图片

    方法一:利用“魔术棒橡皮工具”. 1. 点击“圆角矩形工具”,然后选中打开的背景图片,选中即可. 2.然后,按住“ctrl+enter”,所选边框变为虚线框,然后点击“ctrl+shift+i”反选( ...