洛谷题目链接:切蛋糕

题目描述

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. webpack配置别名alias

    在webpack.config.js中,通过设置resolve属性可以配置查找“commonJS/AMD模块”的基路径,也可以设置搜索的模块后缀名,还可以设置别名alias.设置别名可以让后续引用的地 ...

  2. 用Fluent实现MySQL到ODPS数据集成

    安装ruby 首先通过 /etc/issue 命令查看当前使用centos是哪个版本: [hadoop@hadoop03 ~]$  cat /etc/issue 由于centos版本是6.6,安装ru ...

  3. C++ STL容器——stack用法介绍

    stack是一种容器适配器,专门设计用于在LIFO上下文中操作(后进先出),其中元素仅从容器的一端插入和删除. 容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, ...

  4. matlab mex 小o -o 出错

    https://github.com/kyamagu/mexopencv/issues/117 就是说2014a以后的版本mex   -o 选项变成了 -output 蛋疼,这有什么好改的.找了好久才 ...

  5. sping事务的理解

    阅读数:2020 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤 ...

  6. java线程(1)——三种创建线程的方式

    前言 线程,英文Thread.在java中,创建线程的方式有三种: 1.Thread 2.Runnable 3.Callable 在详细介绍下这几种方式之前,我们先来看下Thread类和Runnabl ...

  7. Java面试题(上)

    2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不少的参考答案也是错误的,于是我花了半个月时间对 ...

  8. velocity模板加载

    http://hi.baidu.com/ly_dayu/item/828b09c5c3c5e547a8ba9409 velocity使用基本来说比较简单,但在加载模板时老出问题,很多初学者经常会遇到找 ...

  9. 关于Assert

    如果没有连1394线debug,assert不影响程序的执行,只会在dbgview里面答应"Assertion xxxx"这样的调试信息. 当连着1394线的时候,OS会被hang ...

  10. Delphi 之 编辑框控件(TEdit)

    TEdit 组件主要用于数据的输入和显示和编辑等操作. AutoSelect 获取组件焦点.该属性只能在单行文本组件使用.值为True为选中.false则不选中. BorderStyle 设置编辑框控 ...