• hdu2191多重背包单调队列优化


    http://acm.hdu.edu.cn/showproblem.php?pid=2191
    模板,果然dp还是要从零开始补/kk

    朴素方法,用 (f(i,j)) 表示考虑前 (i) 个物品,(j) 元钱最多能获得多少价值,下面用 (n) 表示物品种类数,(m) 表示总钱数
    (f(i,j)=max(f(i-1,j-kcdot w_i)+kcdot v_i),kle num_i)

    换一种形式,因为是 (kcdot w_i),所以尝试考虑以下 (j) 除以 (w_i) 的余数,也就是令 (d=jmod w_i)
    (f(i,j)=max(f(i-1,d+kcdot w_i)+(num_i-k)cdot v_i))
    其实就是选了 (num_i-k) 个这种物品,再整理一下就是
    (f(i,j)=max(f(i-1,d+kcdot w_i)-kcdot v_i)+num_icdot v_i)

    所以就可以对于每一个物品,枚举每个 (d),用单调队列维护一下
    对于每个 (d),枚举 (k) 满足 (d+kcdot w_ile m)
    单调队列操作:然后把 (f(i-1,d+w_icdot k)) 入队同时弹出所有比他小的,把所以的 (k',k-k'<num_i) 都出队,因为它们已经不满足此物品个数的要求
    用单调队列的性质取一个最大值和 (f(i,d+kcdot w_i)) 来去 (max) 就行了

    (dle w-1,kle dfrac{m-d}{w})
    所以没做一次单调队列的循环次数就是

    [sum_{d=0}^{w-1}dfrac{m-d}{w}=dfrac{sum_{d=0}^{w-1}m-d}{w}=dfrac{mw-sum_{d=0}^{w-1}}{w}=dfrac{w(m-0.5w+1)}{w}=m-0.5w+1 ]

    也就是 (O(m)),希望没有假,在复杂度这还卡了一会
    所以总复杂度是 (O(nm))

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<map>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN std::puts("")
    #define LL long long
    inline int read(){
    	register int x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    int f[105][105];
    int num[2005],ind[2005],tail,head;
    int n,m;
    int main(){int T=read();while(T--){
    	std::memset(f,0,sizeof f);
    	m=read();n=read();
    	for(reg int w,v,tot,i=1;i<=n;i++){
    		w=read();v=read();tot=read();
    		for(reg int j=1;j<=m;j++) f[i][j]=f[i-1][j];
    		for(reg int d=0;d<w;d++){
    			head=-1;tail=0;
    			for(reg int tmp,k=0;d+w*k<=m;k++){//j=d+w*k
    				tmp=f[i-1][d+w*k]-v*k;
    				while(tail<=head&&num[head]<=tmp) head--;
    				num[++head]=tmp;ind[head]=k;
    				while(tail<=head&&k-ind[tail]>tot) tail++;
    				f[i][d+w*k]=std::max(f[i][d+w*k],num[tail]+v*k);
    			}
    		}
    	}
    	std::printf("%d
    ",f[n][m]);
    }
    	return 0;
    }
    
  • 相关阅读:
    mysql 查看数据库及表大小以及数据库扩容评估
    idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
    mybatis plus 中增删改查及Wrapper的使用
    mybatis plus 主键策略
    搭建 spring boot + mybatis plus 项目框架并进行调试
    jeecg datagrid重新指定数据源
    java 日志脱敏框架 sensitive-新版本0.0.2-深度拷贝,属性为对象和集合的
    java 实现敏感词(sensitive word)工具详解使用说明
    java 日志脱敏框架 sensitive,优雅的打印脱敏日志
    互联网公司OpenAPI链接
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/13090031.html
Copyright © 2020-2023  润新知