买月饼/背包(多重)

题目链接【https://www.oj.swust.edu.cn/problem/show/1194】

题目是中文的。

1、完全背包。2、0-1背包(二进制优化)。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn =10050;
int dp[maxn];
int n,m;
void zero(int w,int v)
{
    for(int i=m;i>=w;i--)
        dp[i]=max(dp[i],dp[i-w]+v);
}
void complet(int w,int v)
{
    for(int i=w;i<=m;i++)
        dp[i]=max(dp[i],dp[i-w]+v);
}
void multi(int w,int v,int num)
{
    if(w*num>=m)
    {
        complet(w,v);
        return ;
    }
    int k=1;
    while(k<num)
    {
        zero(k*w,k*v);
            num-=k;
        k<<=1;
    }
    zero(num*w,num*v);
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        int v,w,t;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&v,&w,&t);
            if(t==-1)
                complet(w,v);
            else
                multi(w,v,t);
        }
        printf("%d
",dp[m]);
    }
    return 0;
}