BZOJ1190_梦幻岛宝珠_KEY
2024-10-20 05:47:33
观察数据a*2^b,转化成二进制后,后面跟了b位的0,可以转化为一个分层背包。
先预处理出每个物品是哪一层的,并放在同层内DP。
同层内直接背包,考虑层与层之间的DP。
第一维枚举层数,然后做类似于背包的DP,细节看code。
code:
/**************************************************************
Problem: 1190
User: yekehe
Language: C++
Result: Accepted
Time:5932 ms
Memory:960 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int read()
{
char c;while(c=getchar(),c!='-'&&(c<''||c>''));
int x=,y=;c=='-'?y=-:x=c-'';
while(c=getchar(),c>=''&&c<='')x=x*+c-'';
return x*y;
} int w[],v[],f[][]; void work(int i)//预处理
{
for(int k=;k<=;k++)
if(w[i]&(<<k)){
for(int j=;j>=(w[i]>>k);j--)
f[k][j]=max(f[k][j-(w[i]>>k)]+v[i],f[k][j]);
return ;
}
} int main()
{
while(){
int N=read(),M=read(),ans=;
if(N<&&M<)break;
memset(f,,sizeof f);
for(int i=;i<=N;i++)
w[i]=read(),v[i]=read();
for(int i=;i<=N;i++)work(i);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
f[i][j]=max(f[i][j],f[i][j-]);
for(int i=;i<=&&<<i<=M;i++){//枚举层数
for(int j=min(,M>>i);j>=;j--){//枚举背包容量,类似01背包转移
for(int k=;k<=j;k++){
f[i][j]=max(f[i][j],f[i-][min((k<<)+(M>>i-&),)]+f[i][j-k]);//k*2是因为从上一层转移。
ans=max(ans,f[i][j]);
}
}
}
printf("%d\n",ans);
}
return ;
}
最新文章
- [转]阿里巴巴数据库连接池 druid配置详解
- 扫描内网活跃的ip
- 解决ScrollView嵌套ListView,ListView填充容器后,界面自动滚动回顶部的问题
- Git学习笔记03--git reset
- 【面试题021】包含min函数的栈
- Android AlarmManager的取消
- POJ1260Pearls
- [Angular 2] ROUTING IN ANGULAR 2 REVISITED
- 数据分析系统DIY3/3:本地64位WIN7+matlab 2012b訪问VMware CentOS7+MariaDB
- 在Centos 5.x或6.x上安装RHEL EPEL Repo
- java 集装箱 arraylist 用法
- ios 添加工程依赖只能生成Generic Xcode Archive 文件原因
- [C#] .Net Core 全局配置读取管理方法 ConfigurationManager
- java设计模式—— 工厂模式
- C# - 为引用类型重定义相等性
- TypeScript 函数-重载
- Unable to construct api.Node object for kubelet: can&#39;t get ip address of node master.example.com: lookup master.example.com on : no such host
- 【linux】之常用命令-杂项
- centos6中搭建tomcat
- RNN文章总结