codevs 5429 完全背包

Posted ziliuziliu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 5429 完全背包相关的知识,希望对你有一定的参考价值。

单调队列优化。

好像有点烦。。。调了许久。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 7050
using namespace std;
long long n,m,v[maxn],w[maxn],c[maxn],up[maxn],q[maxn],l,r,ret1,ret2,val[maxn],dp[maxn];
void get_up(long long x)
{
    for (long long i=0;i<=m%v[x];i++)
        up[i]=(m/v[x])*v[x]+i;
    for (long long i=m%v[x]+1;i<=v[x]-1;i++)
        up[i]=(m/v[x]-1)*v[x]+i;
}
void insert(long long x,long long y,long long z)
{
    while ((l<=r) && (val[r]<=dp[x]-y*w[z])) r--;
    q[++r]=x;val[r]=dp[x]-y*w[z];
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for (long long i=1;i<=n;i++)
        scanf("%lld%lld%lld",&v[i],&w[i],&c[i]);
    for (long long i=1;i<=n;i++)
    {
        get_up(i);
        for (long long j=0;j<v[i];j++)
        {
            l=1;r=0;long long now=up[j],lim=up[j];ret1=ret2=up[j]/v[i];
            while (now>=0)
            {
                while ((l<=r) && (q[l]>now)) l++;
                while ((lim>=now-c[i]*v[i]) && (lim>=0))
                {
                    insert(lim,ret2,i);
                    lim-=v[i];ret2--;
                }
                dp[now]=val[l]+ret1*w[i];ret1--;now-=v[i];
            }
        }        
    }
    printf("%lld\n",dp[m]);
    return 0;
}

 

以上是关于codevs 5429 完全背包的主要内容,如果未能解决你的问题,请参考以下文章

codevs 3961 硬币找零完全背包DP/记忆化搜索

codevs 1795 金字塔 2

CODEVS 3269 混合背包

codevs 3269 混合背包(复习混合背包)

Codevs 3269 混合背包

Codevs 3269-混合背包