链接:https://www.nowcoder.com/acm/contest/80/D
来源:牛客网

最可爱的applese生日啦,他准备了许多个质量不同的蛋糕,想请一些同学来参加他的派对为他庆生,为了不让一部分同学感到不爽,他决定把每个蛋糕都分割成几份(也可以不分割),使得最小的蛋糕的质量与最大的蛋糕的质量的比值不小于一个值。但是applese的刀功并不是很好,所以他希望切尽量少的刀数使得所得到的蛋糕满足条件。由于applese为了保证每一块蛋糕的质量和期望的没有偏差,所以他一刀只能切下一块蛋糕,即将一块蛋糕分成两块,同时,他不能一刀同时切两块蛋糕,也就是说,applese一次只能将一块蛋糕分割成两块指定质量的蛋糕,这两块蛋糕的质量和应等于切割前的蛋糕的质量。Applese还急着准备各种派对用的饰品呢,于是他把这个问题交给了你,请你告诉他至少要切割几次蛋糕

输入描述:

第一行包括两个数T,n,表示有n个蛋糕,最小的蛋糕的质量与最大的蛋糕的质量的比值不小于T
接下来n行,每行一个数wi,表示n个蛋糕的质量

输出描述:

输出包括一行,为最小切割的刀数
数据保证切割次数不超过500
示例1

输入

0.99 3
2000 3000 4000

输出

6

备注:

0.5 < T < 1
1 <= n <= 1000
1 <= wi <= 1000000 题意 :问最小切蛋糕次数,使得所有蛋糕中最小值与最大值的比值大于等于 T
思路分析 :
  首先我们要想的一个问题,蛋糕要怎么切?
  平均切吗?当然是的,我们要确保的答案是最小值与最大值的比值大于等于 T ,只有当平均切的时候,才能使每块蛋糕的质量更加集中,才会使这个比值更大。
  其次就比较好写了,2种方法
  第一种先对蛋糕质量排序,枚举质量最小的一块的切的次数,然后从最大的质量的蛋糕往小的判断即可。
  代码示例 :
  
/*
* parasol
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <time.h>
using namespace std;
#define ll long long
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f; double T;
int n;
double pre[1005], a[1005];
int ans = 0;
int sign = 0; void fun(int x, double mm){
if (sign) return;
if (x == 0) {sign = 1; return; }
double f = mm/pre[x];
if (f > T || fabs(f-T)<eps) { // 一刀不切的时候
sign = 1;
return;
}
for(int i = 1; i <= 500; i++){
double p = (pre[x]/(i+1));
if (mm > p) f = p/mm;
else f = mm/p;
if (f > T || fabs(f-T)<eps) {
fun(x-1, min(mm, p));
}
}
} void fun(int num){
double p = pre[1]/(num+1); for(int i = n; i > 1; i--){
for(int j = 0; j <= 500; j++){
double f = pre[i]/(j+1);
if (fabs(p-f) < eps) {ans += j; break;}
else if (p < f) {
double x = p/f;
if (x > T || fabs(x-T) < eps){
ans+=j;
break;
}
}
else {
double x = f/p;
if (x > T || fabs(x-T) < eps){
ans+=j;
break;
}
}
}
}
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> T >> n;
for(int i = 1; i <= n; i++){
scanf("%lf", &pre[i]);
}
sort(pre+1, pre+1+n);
for(int i = 0; i <= 500; i++){
double mm = pre[1]/(i+1);
fun(n, mm);
if (sign) {
fun(i);
ans += i;
printf("%d\n", ans);
return 0;
}
}
return 0;
}

方法二 、 用优先队列

  将结点定义成

  

struct node
{
int x; // 先前的质量
int cnt; // 切割的次数
int now; // 当前蛋糕的质量
};

每次从队列中取出最大值,看一下符不符合题意,不符合就多切一下

最新文章

  1. IOS开发基础知识--碎片11
  2. jquery 层根据矩形路径移动和闪耀(原创)
  3. Flex Viewer (二)——体系结构
  4. udp 内网穿透 互发消息
  5. 关于webstorm的使用编码的问题
  6. zzzzw_在线考试系统①准备篇
  7. Javascript 风格向导
  8. Binary转换成Hex字符串
  9. iOS 手机时区获取问题
  10. 以@Value方式注入 properties 配置文件
  11. jQuery(五)、筛选
  12. Outlook插件开发(非VSTO),欢迎交流
  13. Mysql漏洞修复方法思路及注意事项
  14. 背水一战 Windows 10 (106) - 通知(Toast): 通过 toast 打开协议, 通过 toast 选择在指定的时间之后延迟提醒或者取消延迟提醒
  15. 第五节:详细讲解Java中的接口与继承
  16. Codeforces 1051E. Vasya and Big Integers
  17. struts2实现jQuery的异步交互
  18. java实现24点游戏代码
  19. vue写template的4种形式
  20. 详细讲解 A/B 测试关键步骤,快来检查下还有哪些疏漏的知识点

热门文章

  1. Acegi框架介绍
  2. vue中动态class写法
  3. ASP.NET MVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(1)
  4. java.util.Date和jdk1.8新时间API比拼
  5. jekyll 在博客添加流程图
  6. 让Word Add-in For MediaWiki支持Word 2013
  7. Python5_学习方法论
  8. C++,Windows/MFC_中L和_T()之区别
  9. SQLite3的使用(封装很长,直接使用sqlite3_open函数,LIBS += sqlite3.dll 即可)good
  10. spring-redis-session 自定义 key 和过期时间