zoukankan      html  css  js  c++  java
  • 【BZOJ1190】[HNOI2007] 梦幻岛宝珠(DP水题)

    点此看题面

    大致题意: 01背包问题。其中物品个数(n≤100),背包容量和每个物品体积(≤2^{30}),且每个物品体积可以表示为(a imes 2^b(1le ale 10,ble 30))

    前言

    大概是我天天念叨总是做不出(DP)题,结果就撞见这样一道水题。

    可是,一道水题都要想好久,还挂了几发,我毕竟还是太菜。

    大致思路

    考虑题目涉及这么多(2)的幂,自然而然就想到从高到低枚举每一位(DP)

    我们假设当前枚举到第(i)位,则我们强制所有体积为(a imes 2^i)的物品都要在此时判断是否选择。

    即,我们假设(DP)到第(i)位我们最多能选体积为(j imes 2^i)的物品(此时忽略末(i)位),那么原本的大背包就被我们转化为对于每一位的小背包。

    那么这样有什么好处呢?

    由于(ale10)的,所以我们可以把(j>10n)时的情况全部归于(j=10n)!(显然吧,因为多余的容量反正用不完,不如直接舍弃)

    大致整理下思路:先枚举(i),然后通过小背包求出(g_k)表示选择体积不超过(k imes 2^i)的物品所能得到的最大代价,再枚举(j)通过刷表法(推荐使用,因为要舍弃多余容量)枚举一个(k)转移(f_{i,j})

    然后算算复杂度,枚举(i)(O(logV)),而刷表法转移(f_{i,j})(O(100n^2))的。(小背包是针对每个物品的,复杂度为(O(10n^2)),此处可以忽略)

    总复杂度是(O(100n^2logV)),看似会(T),但实际上肯定是跑不满的。就连BZOJ上都跑得飞快,你还虚什么!

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg 
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100
    #define pb push_back
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,lim,p[35],f[35][N*10+5],g[N*10+5];
    struct data {int a,v;I data(CI x=0,CI y=0):a(x),v(y){}};vector<data> V[35];
    int main()
    {
    	RI i,j,k,x,y,t,len,ans;vector<data>::iterator it;W(scanf("%d%d",&n,&x),~n&&~x)
    	{
    		len=-1;W(x) p[++len]=x&1,x>>=1;for(i=0;i<=len;++i) V[i].clear();//把背包容量转化为二进制,并清空vector
    		for(i=1;i<=n;++i) {scanf("%d%d",&x,&y),t=0;W(!(x&1)) x>>=1,++t;V[t].pb(data(x,y));}//转化为a*2^b的形式,存入vector
    		for(lim=10*n,i=0;i<=len;++i) for(j=0;j<=lim;++j) f[i][j]=-1;//初始化清空
    		for(f[len][1]=ans=0,i=len;~i;--i)//枚举每一位
    		{
    			for(j=0;j<=lim;++j) g[j]=0;//清空
    			for(it=V[i].begin();it!=V[i].end();++it)//枚举这一位上的物品
    				for(j=lim;j>=it->a;--j) Gmax(g[j],g[j-it->a]+it->v);//小背包
    			for(j=0;j<=lim;++j) for(k=0;k<=j;++k) ~f[i][j]&&//枚举j,k刷表
    				(i&&Gmax(f[i-1][min(j-k<<1|p[i-1],lim)],f[i][j]+g[k]),Gmax(ans,f[i][j]+g[k]));//注意i=0时不再转移
    		}printf("%d
    ",ans);//输出答案
    	}return 0;
    }
    
  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1190.html
Copyright © 2011-2022 走看看