zoukankan      html  css  js  c++  java
  • [luogu P1776] 宝物筛选 解题报告(单调队列优化DP)

    题目链接:

    https://www.luogu.org/problemnew/show/P1776

    题目:

    终于,破解了千年的难题。小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎。但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物。看来小FF只能含泪舍弃其中的一部分宝物了……小FF对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小FF有一个最大载重为W的采集车,洞穴里总共有n种宝物,每种宝物的价值为v[i],重量为w[i],每种宝物有c[i]件。小FF希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大。

    题解:

    很容易写出状态转移方程$dp_{i,j}=max[dp_{i-1,j-w*k}+v*k],k<=c$

    我们要转化为可以单调队列优化的类型

    $dp_{i,j}=max[dp_{i-1,d+w*k}-v*k]+v*s,s=lfloor frac{j}{w} floor,d=j mod w$ 枚举k。

    众所周知,dp优化的原理就是减少不必要的转移,上述这个状态转移方程就是基于发现最初始的状态转移方程里的j只能从j在模w意义下的同余系转移而得到。因而我们枚举余数d

    那么如何用单调队列维护就很显然了,对于每一个余数d维护一个单调队列即可

    代码

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N=4e4+15;
    int n,W,ans,tmp;
    int dp[N],q1[N],q2[N];
    inline int read()
    {
        char ch=getchar();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    int main()
    {
        n=read();W=read();
        for (int i=1;i<=n;i++)
        {
            int v=read(),w=read(),c=read();
            if (w==0)
            {
                ans+=v*c;
                continue; 
            }
            c=min(c,W/w);
            for (int d=0;d<w;d++)//枚举余数 
            {
                int K=(W-d)/w;//最大的整除数 
                int head=1,tail=0;
                for (int k=0;k<=K;k++)//枚举整除数 
                {        
                    int now=dp[d+w*k]-v*k;
                    while (head<=tail&&now>=q1[tail]) --tail;
                    ++tail;
                    q1[tail]=now;
                    q2[tail]=k;
                    while (head<=tail&&c<k-q2[head]) head++;
                    dp[d+w*k]=max(dp[d+w*k],q1[head]+v*k);
                    tmp=max(dp[d+w*k],tmp);
                }
            }
        }
        printf("%d
    ",tmp+ans);
        return 0;
    }
  • 相关阅读:
    Android UI ActionBar功能-ActionBarProvider的使用
    Android UI ActionBar功能-自动隐藏 Action Bar
    Android UI ActionBar功能-Action Bar 左上角的向上或返回按钮
    Android UI ActionBar功能-自定义Tab功能
    Android UI ActionBar功能-自定义 Action Bar 样式
    Android UI ActionBar功能-在 Action Bar 上添加按钮
    Android UI ActionBar功能-启动ActionBar
    AndroidUI 侧滑菜单 DrawerLayout的使用
    AndroidUI 引导页面的使用
    AndroidUI 布局动画-点九PNG技术
  • 原文地址:https://www.cnblogs.com/xxzh/p/10574563.html
Copyright © 2011-2022 走看看