二进制拆分优化

这篇博客探讨了二进制拆分技术在解决多重背包问题和实现快速幂运算中的作用。对于多重背包问题,通过二进制拆分将物品数量转化为0-1背包问题,简化了计算过程。而在快速幂算法中,二进制拆分结合分治思想,实现了高效地计算幂次。两种方法都利用了位操作,提高了算法效率。博客还介绍了两种不同的快速幂实现方式,并强调了边界条件的处理和归并过程的重要性。
摘要由CSDN通过智能技术生成

  之前在学多重背包(涉及三重循环)时曾经大佬教过二进制拆分,今天看到快速幂用了两个方法:分治,二进制拆分。突然就联想到了多重背包,但是想到二进制拆分时又忘记咋做了,特此总结复习。

首先看看多重背包的二进制拆分。
  我们知道多重背包的每种物品有p[i]个,二进制拆分就是要这些个物品按照二进制的方式拆分,然后转化为0-1背包问题求解,不难想到其实应该有一个1 2 4 8…的系数在进行作用。这个系数具体来讲可以说是一个满足 p[i]-pow(2,k)+1>0最大k值形成系数:1,2,4,…,pow(2,k-1)。最后我们还要加上一个防止系数越界的数。
例如p[i]如果为13那么系数就是 1 2 4 6

具体代码如此:

void DP()
{
    for(int i=1;i<=n;i++)
    {
        int num=min(p[i],p[i]/V)//你背包能装多少,如果只能装8个我p[i]也没必要拆分100个啊
        for(int k=1;num>0;k<<=1)
        {
            if(k>num)//边界维护
            {
                k=num;
            }
            num-=k;//边界维护
            for(int j=V;j>=cost[i]*k;j--)
            {
                dp[j]=max(dp[j],dp[j-cost[i]*k]+value[i]*k);
            }
        }
    }
}

我们再来看看快速幂的二进制拆分

void fastpow(int n,int a)//a的n次幂
{
   int ans=1;
   while(n)
   {
       if(n&1)//相当于判断奇数
           ans*=a;//1位有数当乘
       a*=a;//系数进阶
       n>>=1;
   }
   return ans;
}

快速幂的另一种方法是采用了分治的方法(说到这里想起了归并排序)

void fastpow(int n,int a)
{
     if(n==1)
        return a;
     int fpow=fastpow(n/2,a);//细分
     if(n&1)//开始归并
         return fpow*fpow*a
     return fpow*fpow;
}

这个归并也要好好琢磨

很抱歉,由于我是一名语言模型AI,我并不具备直接运行代码的能力。但是,我可以为您提供一些关于多重背包二进制优化输入c代码的信息和建议。 多重背包问题是一种经典的动态规划问题,二进制优化是对传统多重背包算法的一种优化手段,可以大幅提升算法性能。 以下是一个可能的多重背包二进制优化输入c代码的基本框架: ```c #include <stdio.h> #define MAXN 1005 int N; // 物品数量 int W; // 背包总容量 int w[MAXN]; // 每个物品的重量 int v[MAXN]; // 每个物品的价值 int f[MAXN][MAXN]; int max(int a, int b) { return a > b ? a : b; } int main() { scanf("%d %d", &N, &W); for (int i = 1; i <= N; i++) { scanf("%d %d", &w[i], &v[i]); } // 以下为二进制优化部分 int n = 1; for (int i = 1; i <= N; i++) { int k = 1; while (k <= v[i]) { w[n] = k * w[i]; v[n++] = k * v[i]; v[i] -= k; k *= 2; } if (v[i] > 0) { w[n] = v[i] * w[i]; v[n++] = v[i] * v[i]; } } N = n - 1; // 多重背包部分 for (int i = 1; i <= N; i++) { for (int j = W; j >= w[i]; j--) { for (int k = 1; k * w[i] <= j; k++) { f[j] = max(f[j], f[j - k * w[i]] + k * v[i]); } } } printf("%d\n", f[W]); return 0; } ``` 以上代码实现了基于二进制优化多重背包问题,通过对每个物品按其价值进行二进制拆分,并将其转化为多个物品,以便于后续的多重背包求解。 需要注意的是,该算法的时间复杂度为 $O(NV\log V)$,其中 $V$ 为所有物品的总价值。如果您需要更高效的算法实现,可以尝试其他优化技巧,如单调队列优化、有界背包优化等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值