- 贪心:对于同样的蛋糕,相比于给嘴大的人吃,给嘴小的人吃可以满足更多人。优先将蛋糕喂给嘴小的人可以获得局部最优解。
- 判断:判断一个局部最优解是不是整体最优解,只能通过
暴力的搜索的方式。但是这样的话会消耗很多的时间。 - 二分:此题答案可行域连续,可以使用二分查找确定答案,再由搜索验证答案是否合理以缩小区间直到可以确定最优解。
random_shuffle
,随机打乱一个数组。我们对于蛋糕多random_shuffle
几遍
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
int n, m, cke[MAXN + 10], mth[MAXN + 10], qz[MAXN + 10], cp[MAXN + 10], sum = 0;
bool flag = 0;
bool check(int mid) {
for(int p = 1; p <= 1500; p++) {
for(int i = 1; i <= n; i++) cp[i] = cke[i];
random_shuffle(cp + 1, cp + n + 1);
bool eye = 0;//表示这样的蛋糕排列行不行
for(int i = mid; i >= 1; i--) {//枚举每个嘴
bool flag = 0;
for(int j = 1; j <= n; j++) {//枚举每个蛋糕
if(cp[j] >= mth[i]) {//能吃,吃
cp[j] -= mth[i];
flag = 1; break;
}
}
if(!flag) {//如果不行,标记
eye = 1;
break;
}
}
if(!eye) return 1;//如果都行,直接返回
}
return 0;//mid 人不行
}
int main() {
cin >> n; for(int p = 1; p <= n; p++) cin >> cke[p];
cin >> m; for(int p = 1; p <= m; p++) cin >> mth[p];
sort(mth + 1, mth + m + 1);
int l = 1, r = m;
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) l = mid + 1;
else r = mid - 1;
}
cout << r << endl;
}