链接:点击打开链接
题目描述
最可爱的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
题解:
这题开始没做出来,因为感觉情况会非常的复杂,没有一点思路。但是看到了官方题解就很厉害了
首先有一个结论,每块蛋糕分成的每一块的大小都是相同的
基于这个结论,每次找到当前划分最大块所在的大块并将其划分数+1,
检查是否满足题目的要求考虑这个结论为什么是正确的:考虑一个蛋糕切的刀数不变,那么可以想到假如分割得到的块是不同的,那么可能的献是增加最大和最小之间的差值,那么这样答案只会更劣,所以可以想到分成的每个块的大小是相同的那么只要按照上面模拟就可以了,这题妥妥的送温暖。
基于这个思想,我使用了map
#include <bits/stdc++.h>
#define mp(a,b) make_pair(a,b)
using namespace std;
struct Node{
double ave,all;
int div;
}E[1007];
multimap<double,int> mp;
multimap<double,int>::iterator it,it2,i;
void show(){
i = mp.begin();
for (;i != mp.end();i ++){
cout << i->first << ',' << i->second << endl;
}
cout << "****************************" << endl;
}
int main()
{
ios::sync_with_stdio(false);
double des;
int n;
cin >> des >> n;
for (int i = 1;i <= n;i ++){
cin >> E[i].all;
E[i].div = 1;
E[i].ave = E[i].all;
mp.insert(mp(E[i].ave,i));
}
it = mp.begin();
it2 = mp.end();it2--;
//show();
if (n == 1)cout << 0 << endl;
else {
int ans = 0;
while (it->first/it2->first < des){
int ID = it2->second;
E[ID].div ++;
E[ID].ave = E[ID].all/E[ID].div;
mp.erase(it2);
mp.insert(mp(E[ID].ave,ID));
it2 = mp.end();it2--;
it = mp.begin();
ans ++;
//show();
}
cout << ans << endl;
}
}