题目链接: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; } };