leetcode1799. N 次操作后的最大分数和(状压dp)

题面

程序

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();
        // dp[i]:i看成二进制数,所有为1的位数表示还没有选,0的位数表示已经选过了。
        //表示所有状态为i的情况下开始,继续游戏的所有操作的集合
        //属性(值)表示得分最大值
        vector<int> dp(1<<n);
        //转移方程为dp[i]=max(dp[j]+第k步*gcd(x,y))x,y为下一步的一种选法)
        //第k步的求法:看i的二进制表示中有s个0,则为第s/2+1步
        
        for(int i=0;i<1<<n;i++){
            int s=0;
            //求第k步的k
            for(int j=0;j<n;j++){
                if((i>>j&1)==0){
                    s++;
                }
            }
            s=s/2+1;
            //此时为第s步

            // 枚举所有取法,C(n,2)
            for(int j=0;j<n;j++){
                if((i>>j&1)==1){
                    for(int k=j+1;k<n;k++){
                        if((i>>k&1)==1){
                            dp[i]=max(dp[i],dp[i-(1<<j)-(1<<k)]+gcd(nums[j],nums[k])*s);
                        }
                    }
                }
            }
        }
        return dp[(1<<n)-1];
    }
};

vector<int> dp(N) 

vector中将包含7个元素,默认每个元素为0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值