题意: 给你 nums ,它是一个大小为 2 * n 的正整数数组。你必须对这个数组执行 n 次操作。 在第 i 次操作时(操作编号从 1 开始),你需要: 选择两个元素 x 和 y 。 获得分数 i * gcd(x, y) 。 将 x 和 y 从 nums 中删除。 请你返回 n 次操作后你能获得的分数和最大为多少。 函数 gcd(x, y) 是 x 和 y 的最大公约数。 数据范围: 1 <= n <= 7 nums.length == 2 * n 1 <= nums[i] <= 1e6 解法: 令d[i][j]表示i次操作,当前剩余数状态为j的最大权值和.其中j是一个二进制数. 枚举j中未使用的数的下标x和y进行转移. d[i][j]可以转移到d[i+1][j^(1<<x)^(1<<y)],转移收益为gcd(a[x],a[y]). code: int d[10][(1<<14)]; class Solution { public: int maxScore(vector<int>& a) { int n=a.size(); for(int i=0;i<=n/2;i++){ for(int j=0;j<(1<<n);j++){ d[i][j]=-2e9; } } d[0][(1<<n)-1]=0; for(int i=0;i<n/2;i++){ for(int j=0;j<(1<<n);j++){ if(d[i][j]==-2e9)continue; for(int x=0;x<n;x++){ if(j>>x&1){ for(int y=x+1;y<n;y++){ if(j>>y&1){ int t=__gcd(a[x],a[y]); int nt=(j^(1<<x)^(1<<y)); d[i+1][nt]=max(d[i+1][nt],d[i][j]+(i+1)*t); } } } } } } return d[n/2][0]; } };