状态压缩dp

iii 是 nnn 位二进制数,某一位是 111 表示这个数可以选, 000 表示这个数已选过 , f[i]f[i]f[i] 表示当前状态的最大分数和 。一次选两个数。当所有数都选过, f[0]f[0]f[0] 表示选择所有数的最大分数和。
状态转移方程 :
f[i−(1<<j)−(1<<k)]=max(f[i−(1<<j)−(1<<k)],f[i]+gcd(nums[j],nums[k])×cnt)f[i-(1<<j)-(1<<k)]=max(f[i-(1<<j)-(1<<k)],f[i]+gcd(nums[j],nums[k])\times cnt)f[i−(1<<j)−(1<<k)]=max(f[i−(1<<j)−(1<<k)],f[i]+gcd(nums[j],nums[k])×cnt)
class Solution {
public:
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int maxScore(vector<int>& nums) {
int n = nums.size();
int f[1<<n];
memset(f,0,sizeof f);
for(int i = (1<<n)-1;i;i--){
// int cnt = __builtin_popcount(i)/2;
int cnt = 0;
for(int j = 0 ;j<n;j++)
if(!(i>>j&1)) cnt++;
cnt = cnt/2+1;
for(int j = 0;j<n;j++)
if(i>>j&1)
for(int k = j+1;k<n;k++)
if(i>>k&1)
f[i-(1<<j)-(1<<k)] = max(f[i-(1<<j)-(1<<k)],f[i]+gcd(nums[j],nums[k])*cnt);
}
return f[0];
}
};
AC

致语
- 理解思路很重要!
- 欢迎读者在评论区留言,墨染看到就会回复的。
这篇博客探讨了一种使用动态规划和状态压缩技术解决的最大分数和问题。状态转移方程展示了如何通过计算两个数的最大公约数并更新状态来找到所有数都被选择时的最大分数。作者强调理解思路的重要性,并鼓励读者在评论区交流。
&spm=1001.2101.3001.5002&articleId=128408892&d=1&t=3&u=2be22502ab0e4c5888db9eb4c050598a)
1万+

被折叠的 条评论
为什么被折叠?



