题解/算法 {3007. 价值和小于等于 K 的最大数字}

这篇文章介绍了如何使用数位动态规划解决LeetCode上的一个问题,即找到一个最大数字,其价格之和不超过给定的K,且特殊子集中0的处理方法。作者通过遍历数位和特殊子集的分析,提供了一个递归函数来确定符合条件的数字。
摘要由CSDN通过智能技术生成

题解/算法 {3007. 价值和小于等于 K 的最大数字}

@LINK: https://leetcode.cn/problems/maximum-number-that-sum-of-the-prices-is-less-than-or-equal-to-k/description/

参见@LINK: (https://editor.csdn.net/md/?articleId=130768151)-(@LOC_0);
遍历所有数位这是个算法模板(即数位DP所使用的核心算法), 遍历[0...R]的所有数的数位, 即遍历R的所有数位 对于[pre i ?] 其中pre,i是确定的 而?里面 他的每个数位里 {0,1}出现的次数是相同的 都是tot/2个(tot是该子集的大小), 因此可以计算出每个非特殊子集里面1的个数;
但是问题在于 *特殊子集0?*是不满足这个性质的, 因为要去掉前导零 即根据上面的性质 {0,1}都是有tot/2个 但是0的个数是错误的, 但是这个性质仍然可用! 因为题目不会涉及到0 我们求的是1 因此依然可行;

    long long findMaximumNumber(long long K, int X) {
        auto check = [&]( int64_t _mid)->bool{
            auto vec = Integer::IntegerToVector( _mid, -1, 2);
            std::reverse( vec.begin(), vec.end()); // 让`vec`的低位是数字低位;
            auto kk = K;
            FOR_( i, 1, vec.size()){
                if( (i%X==0) && (vec[i-1]==1)){ -- kk; if(kk<0){ return 0;}}
            }
            FOR_( i, 1, vec.size()){
                if( vec[i-1] == 1){ // 枚举让该位放`0`, 即所有形如`[pre 0 ?]`的数;
                    auto tot = (1LL << (i-1));
                    FOR_( j, 1, vec.size()){
                        if( j < i){
                            if( j%X == 0){ kk -= (tot / 2);  if(kk<0){ return 0;}}
                        }
                        else if( j > i){
                            if( (j%X==0) && (vec[j-1]==1)){ kk -= (tot);  if(kk<0){ return 0;}}
                        }
                    }
                }
            }
             if(kk<0){ return 0;}
             return 1;
        };
        int64_t l = 0, r = 4e18;
        while( l < r){
            auto mid = (l+r+1)>>1;
            if( check( mid)){ l = mid;}
            else{ r = mid - 1;}
        }
        ASSERT_( check(r));
        return r;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值