zoukankan      html  css  js  c++  java
  • 单调队列优化多重背包(学习笔记)

    学习博客:https://rpdreamer.blog.luogu.org/bei-bao-wen-ti

    f[mo+k*w[i]]=q[head]+k*c[i];

    这一步没有搞懂啊,说好的最后应该加上 a*c[i] 的呢

    洛谷P1776 宝物筛选

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 100010;
    
    int n,m,ans;
    int head,tail;
    int c[maxn],w[maxn],num[maxn];
    int f[maxn];
    
    int q[maxn],pos[maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f;}
    
    int main(){
        n=read(),m=read();
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            c[i]=read(),w[i]=read(),num[i]=read();
            if(w[i]==0){
                ans+=num[i]*c[i];
                continue;
            }
            if(num[i]>(m/w[i])) num[i]=m/w[i];
            for(int mo=0;mo<w[i];mo++){
                head=1,tail=0;
                for(int k=0;k<=(m-mo)/w[i];k++){
                    int x=f[mo+k*w[i]]-k*c[i];
                    while(head<=tail && q[tail]<=x) tail--;
                    q[++tail]=x; pos[tail]=k;
                    while(head<=tail && pos[head]<k-num[i]) head++;
                    f[mo+k*w[i]]=q[head]+k*c[i];
                }
            }
        }
        
        printf("%d\n",ans+f[m]);
        
        return 0;
    }
  • 相关阅读:
    谈一下ACM的入门书籍及方法
    acm总结帖_By AekdyCoin
    楼天城楼教主的acm心路历程
    弱校ACM奋斗史
    【转】编程的浅学习与深学习
    HDOJ 1047 Integer Inquiry (大数)
    【链性栈】表达式求值
    【链性栈】基本链性栈的实现
    Beta冲刺博客
    Alpha项目测试
  • 原文地址:https://www.cnblogs.com/tuchen/p/10449192.html
Copyright © 2011-2022 走看看