多重背包的二进制分组优化

\(A\)$i,j$表示第\(i\)种物品拆分出的第\(j\)种物品,则\(A\)$i,j$表示由\(2^j\)单个物品捆绑成的大物品

例题

宝物筛选

代码

#include <bits/stdc++.h>
#define i64 long long
using namespace std ;
int n, W ;
struct Node{
    int w ;
    int v ;
    int m ;
}lis[1000005];
i64 dp[100005] ;
int main()
{
    int cnt = 1 ;
    cin >> n >> W ;
    for(int i = 1 ; i <= n ; i ++ )
    {
        int c = 1 ;
        int p , h , k ;
        cin >> p >> h >> k ;
        for(int j = 1 ; j <= k ; j <<= 1)
        {
            lis[++cnt].v = j * p ;
            lis[cnt].w = j * h ;
            k -= j ;
        }
        if(k)
        {
            lis[++cnt].v = p * k ;
            lis[cnt].w = h * k ;
        }
    }
    for(int i = 1 ; i <= cnt ; i ++ )
    {
        for(int j = W ; j >= lis[i].w ; j -- )
        {
            dp[j] = max(dp[j], dp[j - lis[i].w] + lis[i].v) ;
        }
    }
    cout << dp[W] << endl ;
    return 0 ;
}
posted @ 2023-04-25 23:12  Lwen1243  阅读(41)  评论(0)    收藏  举报