Leetcode 2172. 数组的最大与和(状态压缩)

1.题目

2.求解

这是一道隐藏的状态压缩题,我看到第一眼,根本没想到是状压dp。常态的状压dp题是使用二进制保存数据的当前状态,而这里面的状态一般只有取(1)和不取(0),这也是我们最常用的。

但是在本题中,为三进制状压dp,三进制保存篮子里已存放了0, 1, 2个整数,不像二进制可以使用GCC中的 __builtin_popcount() 函数可以直接获得当前存放到第几个整数。三进制需要我们手动遍历求余取和。除此之外,在状态转移方程的位置二进制可以直接使用位运算 1<<n,但是三进制需要手动更新数据。

所幸的是,除了三进制的点,其他的都是套用模板即可。但是根据这道题下次是否可以使用其他进制呢?只要n够小,只要内存够,应该就能用来求解对应的题目。

        学到了新的知识,第一次碰到这种非常规进制的状压题目,很有趣!

3.代码

int nums[20];
const int maxn = 19690;
class Solution {
public:
    int maximumANDSum(vector<int>& nums, int numSlots) {
        
		int nummax = pow(3, numSlots);
        int dp[nummax];
        memset(dp, -1, sizeof(dp));
		dp[0] = 0;
		int ans = 0;
        int i, j, k;
        int n = nums.size();
		for (i = 0; i < nummax; i++) {
			if (dp[i] == -1) continue;
			int cnt = 0;
			int sta = i;
			while (sta > 0) {
				cnt += (sta % 3);
				sta /= 3;
			}
			if (cnt == n) {
				ans = max(ans, dp[i]);
				continue;
			}
			int cur;

			for (j = i, cur = 1, k = 1; k <= numSlots; j /= 3, cur *= 3, k++) {
				if (j % 3 == 2) continue;
				dp[i + cur] = max(dp[i + cur], dp[i] + (nums[cnt] & k));
			}
		}
		return ans;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值