C++ 动态规划 多重背包问题II (多重背包问题的二进制优化)

C++ 动态规划 多重背包问题II (多重背包问题的二进制优化)_第1张图片
可以先把物品拆分(拆分成1 2 4 8 16 … 2^k,并且小于s),然后做一遍01背包问题就可以了,这样可以将时间复杂度从NVS优化到NVlogS。

#include 
#include 

using namespace std;

const int N = 100000, M = 2010; //N 数组是表示打包后的物品,开够就行。
int n, m;
int v[N], w[N];
int f[N];


int main ()
{
    cin>>n>>m;
    int cnt = 0; //打包后物品的下标
    for(int i = 1; i <= n; i ++ )
    {
        int a, b, s;
        cin>>a>>b>>s;
        int k = 1; //从1开始分,下面开始打包了,对于每种物品的所有个数,打包
        while(k <= s)
        {
            cnt ++;
            v[cnt] = a * k;
            w[cnt] = b * k;
            s -= k;
            k *= 2;
        }
        if(s > 0)
        {
            cnt ++;
            v[cnt] = a * s;
            w[cnt] = b * s;
        }
    }
    n = cnt;
    for(int i = 1; i <= n; i ++ ) //01背包求解
        for(int j = m; j >= v[i]; j -- )
            f[j] = max(f[j], f[j - v[i]] + w[i]);
            
            
    cout<<f[m]<<endl;
    
    return 0;    
    
}

你可能感兴趣的:(力扣,动态规划,算法笔记,c++,动态规划)