1. 程式人生 > >【NEFU 1271】多重揹包優化

【NEFU 1271】多重揹包優化

最近的一場比賽我才發現多重揹包原來還能優化,WA了無數次?,後來百度才發現

這道題就是一道多重揹包優化的模板題,而優化有兩種方式,一種是二進位制優化,一種是優先佇列優化

首先是二進位制優化,按照01揹包,迴圈從1~n,但優化後是1,2,4,8,按二進位制來迴圈,因為不同的二進位制相加可以得到1~n-m的所有數,m指的是有一些數到不了,比如1,2,4,相加不能得8

上程式碼吧

#include <map>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f

using namespace std;

const int maxn=100005;

struct node
{
    int wig;
    int val;
    int num;
} a[105];

long long dp[maxn];

int main()
{
    int n,w;
    scanf("%d%d",&n,&w);
    int i,j,x,m;
    for(i=0; i<n; i++)
    {
        scanf("%d%d%d",&a[i].wig,&a[i].val,&a[i].num);
    }
    for(i=0; i<n; i++)
    {
        for(j=1;j<<1<a[i].num;j<<=1)
        {
            for(x=w;x>=j*a[i].wig;x--)
            {
                dp[x]=max(dp[x],dp[x-j*a[i].wig]+j*a[i].val);
            }
        }
        m=a[i].num-j+1;
        for(j=w;j>=m*a[i].wig;j--)
        {
            dp[j]=max(dp[j],dp[j-m*a[i].wig]+m*a[i].val);
        }
    }
    printf("%lld\n",dp[w]);
    return 0;
}