LeetCode 1815 - 得到新鲜甜甜圈的最多组数

题目链接:LeetCode 1815. 得到新鲜甜甜圈的最多组数(第 49 场双周赛第 4 题)

方法一:模拟退火

前置知识

模拟退火例题和模板:计蒜客 A2141 - Country Meow

思路

在这里我们可以把 group 数组看作状态,每次随机选取两个位置进行交换看成增量。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
public:
vector<int> groups;
int batchSize, ans, n;

int calculate() {
int cur = 0, cur_ans = 0;
for (int i = 0; i < n; ++i) {
if (cur == 0) {
cur_ans++;
}

cur += groups[i];
cur %= batchSize;
}

ans = max(ans, cur_ans);

return cur_ans;
}

void simulated_anneling() {
random_shuffle(groups.begin(), groups.end());

for (double t = 1e6; t > 1e-5; t *= 0.98) {
int a = rand() % n, b = rand() % n;
int pre = calculate();
swap(groups[a], groups[b]);
int aft = calculate();
int delta = pre - aft;

if (!(exp(-delta / t) > (double)rand() / RAND_MAX)) {
swap(groups[a], groups[b]);
}
}
}

int maxHappyGroups(int batchSize_, vector<int>& groups_) {
groups = groups_;
batchSize = batchSize_;
ans = 0;
n = groups.size();

srand(time(0));
for (int i = 0; i < 30; ++i) {
simulated_anneling();
}

return ans;
}
};