日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 1799. N 次操作后的最大分数和(回溯 / 状态压缩DP)

發(fā)布時間:2024/7/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 1799. N 次操作后的最大分数和(回溯 / 状态压缩DP) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 錯誤解
      • 2.2 回溯超時解
      • 2.3 回溯通過
      • 2.4 狀態(tài)壓縮DP

1. 題目

給你 nums ,它是一個大小為 2 * n 的正整數(shù)數(shù)組。
你必須對這個數(shù)組執(zhí)行 n 次操作。

在第 i 次操作時(操作編號從 1 開始),你需要:

  • 選擇兩個元素 x 和 y 。
  • 獲得分數(shù) i * gcd(x, y) 。
  • 將 x 和 y 從 nums 中刪除。

請你返回 n 次操作后你能獲得的分數(shù)和最大為多少。

函數(shù) gcd(x, y) 是 x 和 y 的最大公約數(shù)。

示例 1: 輸入:nums = [1,2] 輸出:1 解釋:最優(yōu)操作是: (1 * gcd(1, 2)) = 1示例 2: 輸入:nums = [3,4,6,8] 輸出:11 解釋:最優(yōu)操作是: (1 * gcd(3, 6)) + (2 * gcd(4, 8)) = 3 + 8 = 11示例 3: 輸入:nums = [1,2,3,4,5,6] 輸出:14 解釋:最優(yōu)操作是: (1 * gcd(1, 5)) + (2 * gcd(2, 4)) + (3 * gcd(3, 6)) = 1 + 4 + 9 = 14提示: 1 <= n <= 7 nums.length == 2 * n 1 <= nums[i] <= 10^6

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/maximize-score-after-n-operations
著作權歸領扣網(wǎng)絡所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權,非商業(yè)轉(zhuǎn)載請注明出處。

2. 解題

2.1 錯誤解

  • 貪心取最大的得分組合,有可能不是最佳方案,[481851,31842,817070,452937,627635,712245]最后的例子過不了
class Solution { public:int maxScore(vector<int>& nums) {vector<vector<int>> g(nums.size(),vector<int>(nums.size()));priority_queue<tuple<int, int, int, int>> q;for(int i = 0; i < nums.size(); ++i){for(int j = i+1; j < nums.size(); ++j){g[i][j] = __gcd(nums[i], nums[j]);for(int k = 1; k <= nums.size()/2; ++k){q.push(tuple(k*g[i][j], i, j, k));}}}vector<bool> vis(nums.size(), false), visk(nums.size()/2+1, false);int count = nums.size()/2;int ans = 0;while(count){auto [p, i, j, k] = q.top();q.pop();if(vis[i] || vis[j] || visk[k])continue;vis[i] = true;vis[j] = true;visk[k] = true;count--;ans += p;}return ans;} };

2.2 回溯超時解

  • 通過 46/66
class Solution {int maxS = 0; public:int maxScore(vector<int>& nums) {vector<bool> vis(nums.size(), false);sort(nums.begin(),nums.end());vector<vector<int>> g(nums.size(),vector<int>(nums.size()));for(int i = 0; i < nums.size(); ++i){for(int j = i+1; j < nums.size(); ++j){g[i][j] = __gcd(nums[i], nums[j]);}}dfs(nums, 0, 0, vis, g);return maxS;}void dfs(vector<int>& nums, int ct, int p, vector<bool>& vis, vector<vector<int>> &g){if(ct == nums.size()/2){if(p > maxS)maxS = p;return;}int i = 0, j;for( ; i < nums.size(); ++i){if(!vis[i]){vis[i] = true;for(j=i+1 ; j < nums.size(); ++j){if(!vis[j]){vis[j] = true;dfs(nums, ct+1, p+(ct+1)*g[i][j], vis, g);vis[j] = false;}}vis[i] = false;}} } };

2.3 回溯通過

class Solution {int maxS = 0; public:int maxScore(vector<int>& nums) {vector<bool> vis(nums.size(), false);vector<vector<int>> g(nums.size(),vector<int>(nums.size()));for(int i = 0; i < nums.size(); ++i){for(int j = 0; j < nums.size(); ++j){g[i][j] = __gcd(nums[i], nums[j]);}}vector<int> path;dfs(nums, 0, vis, g, path);return maxS;}void dfs(vector<int>& nums, int idx, vector<bool>& vis, vector<vector<int>> &g, vector<int>& path){if(idx == nums.size()/2){int s = 0;vector<int> v = path;sort(v.begin(), v.end());for(int i = 0; i < v.size(); i++){s += (i+1)*v[i];}maxS = max(maxS, s);return;}int i = 0, j = 0;for( ; i < nums.size(); ++i){if(vis[i]) continue;break;}vis[i] = true;for( ; j < nums.size(); ++j){if(!vis[j]){vis[j] = true;path.push_back(g[i][j]);dfs(nums, idx+1, vis, g, path);path.pop_back();vis[j] = false;}}vis[i] = false;} };

884 ms 82.7 MB C++

2.4 狀態(tài)壓縮DP

class Solution { public:int maxScore(vector<int>& nums) {int n = nums.size(), cti, ctj;vector<int> dp(1<<n);for(int i = 0; i < n; ++i){for(int j = i+1; j < n; ++j)dp[(1<<i)|(1<<j)] = __gcd(nums[i], nums[j]);}for(int i = 0; i < (1<<n); ++i){cti = count(i);if(cti%2 == 1) continue;for(int j = i; j>0; j=(j-1)&i){ctj = count(j);if(cti-ctj == 2)// 相差一對數(shù),從 j 轉(zhuǎn)移到 i{dp[i] = max(dp[i], dp[j]+cti/2*dp[i^j]);}}}return dp[(1<<n)-1];}int count(int x){ // 計算二進制1個數(shù)int s = 0;while(x){s++;x = x&(x-1);}return s;} };

140 ms 8.2 MB C++


我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!

總結

以上是生活随笔為你收集整理的LeetCode 1799. N 次操作后的最大分数和(回溯 / 状态压缩DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。