[HNOI2007]梦幻岛宝珠
时间:2019-09-28
本文章向大家介绍[HNOI2007]梦幻岛宝珠,主要包括[HNOI2007]梦幻岛宝珠使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题意简洁明了,就是做一个01背包,但是背包的容量\(W\)非常大,并且给出的物品的体积都能表示成\(a\times 2^b,a\leq 10,b\leq 30\)
显然这个\(a\)拿来做背包的体积非常合适,于是我们按照\(b\)分类,设\(dp_{i,j}\)表示只使用\(a\times 2^i\)形式的物品,凑出\(j\times 2^i\)体积的最大价值
其实就是对每一种\(b\)单拎出来做一个01背包
考虑合并掉\(dp\)数组,设\(f_{i,j}\)表示合并出一个形如\(j\times2^i\)并且后\(i-1\)位都不超过\(W\)后\(i-1\)位的最大价值
不难发现我们的答案就是\(\max(f_{\log w,0},f_{\log w,1})\)
合并的时候也大力转移,我们枚举一下\(i-1\)位给\(i\)进多少位,则有
\[f_{i,j}=\max_{k=0}f_{i-1,2\times k+w_{i-1}}+dp_{i,k-j}\]
代码
#include<bits/stdc++.h>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int a[31][105],b[31][105];
int dp[31][1005],f[31][2005];
int sum[31],cnt[31],n,m,bit[31],tot,S[31];
int main() {
while(1) {
scanf("%d%d",&n,&m);
if(n==-1&&m==-1) return 0;tot=0;
for(re int i=0;i<=30;++i) cnt[i]=0,S[i]=0;
memset(dp,0,sizeof(dp));memset(f,0,sizeof(f));
for(re int w,v,i=1;i<=n;i++) {
w=read(),v=read();
for(re int j=0;j<=30;++j) {
if(w/(1<<j)<=10) {
a[j][++cnt[j]]=w/(1<<j),b[j][cnt[j]]=v;
S[j]+=a[j][cnt[j]];
break;
}
}
}
for(re int i=0;i<=30;++i)
for(re int j=1;j<=cnt[i];++j)
for(re int k=S[i];k>=a[i][j];--k)
dp[i][k]=max(dp[i][k],dp[i][k-a[i][j]]+b[i][j]);
sum[0]=S[0];
for(re int i=1;i<=30;++i) sum[i]=sum[i-1]/2+1+S[i];
for(re int i=0;i<=S[0];++i) f[0][i]=dp[0][i];
while(m) bit[tot++]=(m&1),m>>=1;tot--;
for(re int i=1;i<=tot;++i)
for(re int j=0;j<=sum[i];++j)
for(re int k=0;k<=j&&k<=S[i];++k) {
if(2*(j-k)+bit[i-1]<=sum[i-1])
f[i][j]=max(f[i][j],dp[i][k]+f[i-1][2*(j-k)+bit[i-1]]);
else f[i][j]=max(f[i][j],dp[i][k]+f[i-1][sum[i-1]]);
}
int ans=max(f[tot][0],f[tot][1]);
for(re int i=0;i<tot;++i)
ans=max(ans,max(f[i][0],f[i][1]));
printf("%d\n",ans);
}
return 0;
}
原文地址:https://www.cnblogs.com/asuldb/p/11603791.html
- Kubernetes服务网格(第8部分):Linkerd作为入口控制器
- 使用RestSharp 库消费Restful Service
- Python-面向对像及其他
- 基于MongoDB GridFS的图片存储
- css3 过渡和2d变换——回顾
- Microsoft 防跨站点脚本库AntiXSS Library v4.2.1
- Compilify——让你在浏览器中编译.NET代码
- Python进阶-面向对象
- WCF RESTful服务的Google Protocol Buffers超媒体类型
- 使用CoreOs,Docker和Nirmata部署微服务类型的应用
- .NET 4 上的REST 框架
- 结合游戏开发与人工智能研究,游戏大厂 Ubisoft 成立AI研发部门
- Quartz.NET的管理工具
- Python-执行系统命令
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos定制rpm包、搭建yum仓库的教程
- linux手动、自动更改网卡MAC地址的方法
- Centos7的Firewalld防火墙基础命令详解
- Linux下安装或升级Python 2.7的操作方法
- Linux中git用https连接时不用每次输入密码的方法
- Centos7.3 RabbitMQ分布式集群搭建示例
- Ubuntu16.04环境下搭建FTP服务器的教程
- Linux 查看空间使用情况的实例详解
- CentOS 6.8 安装vsftpd的方法步骤
- centos7下搭建ZooKeeper3.4中间件常用命令小结
- Linux性能测试 pmap命令详解
- Linux7.7设置交换分区SWAP的方法
- 在Linux里安装和启动nginx的方法
- Linux下如何对ISO文件编辑的方法示例
- Linux中创建新用户并赋予指定目录的相关权限