HDU 3732 Ahui Writes Word(多重背包)
HDU 3732 Ahui Writes Word(多重背包)
http://acm.hdu.edu.cn/showproblem.php?
pid=3732
题意:
初始有N个物品, 每一个物品有cost[i]花费和val[i]价值, 你有m元钱, 如今问你最多能买多少总价值的物品?
当中N<=10W, m<=1W. 且cost[i]和val[i]都在[0,10]范围.
分析:
本题初看直接用01背包来做是直观的想法. 可是考虑到01背包的复杂度为O(N*m), 这么大的复杂度肯定不行.
然后我们发现事实上每种物品仅仅与它的cost[i]和val[i]有关, 假设某两个物品的cost[i]和val[i]全然相等, 我们能够把这两种物品合并(看出一种物品可是数量叠加), 终于我们直接解决一个多重背包问题就可以. 假设是多重背包问题,
复杂度为O(m*sum( log(num[i]) ) ) 当中 num[i]的和为N.
初始我们读取输入, 然后我们把全部的物品排序,然后在分类之后就构成了n种物品, 每种物品具有num[i]个的多重背包问题.
令dp[i][j]==x 表示购买前i种物品时总花费<=j时, 能够获得的最大价值为x.
初始化: dp全为0.
对于第i种商品, 有以下两种情况:
假设val[i]*num[i]>=m, 就做一次全然背包.
假设val[i]*num[i]<m, 就把第i种物品又一次分类, 并做k+1次01背包.
终于所求: dp[n][m]的值.
程序实现, 用的滚动数组逆向递推, 所以dp仅仅有[j]一维.
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=121+5; int n;//合并之后n种物品
int m;//最大花费值
int val[maxn]; //新分类i物品价值
int num[maxn]; //新分类i物品数目
int cost[maxn];//新分类i物品花费
int dp[10000+5]; //1次01背包过程
void ZERO_ONE_PACK(int cost,int val)
{
for(int i=m;i>=cost;i--)
dp[i] = max(dp[i], dp[i-cost]+val);
} //1次全然背包过程
void COMPLETE_PACK(int cost,int val)
{
for(int i=cost;i<=m;i++)
dp[i] = max(dp[i], dp[i-cost]+val);
} //1次多重背包过程
void MULTIPLY_PACK(int cost,int val,int sum)
{
if(cost*sum>=m)
{
COMPLETE_PACK(cost,val);
return ;
} int k=1;
while(k<sum)
{
ZERO_ONE_PACK(cost*k,val*k);
sum-=k;
k*=2;
}
ZERO_ONE_PACK(cost*sum, val*sum);
} //Node用于保存原始输入的每一个单词属性
struct Node
{
int v,c;
bool operator<(const Node &rhs)const
{
return v<rhs.v || (v==rhs.v && c<rhs.c);
}
bool operator==(const Node &rhs)const
{
return v==rhs.v && c==rhs.c;
}
}nodes[100000+5];
int N;//原始N个单词 int main()
{
while(scanf("%d%d",&N,&m)==2)
{
//读取输入
for(int i=1;i<=N;i++)
{
char str[20];
scanf("%s %d%d",str,&nodes[i].v,&nodes[i].c);
} //将原始输入物品合并再分类
sort(nodes+1,nodes+N+1);
n=1;
val[n]=nodes[1].v;
cost[n]=nodes[1].c;
num[n]=1;
for(int i=2;i<=N;i++)
{
if(nodes[i]==nodes[i-1])
num[n]++;
else
{
n++;
val[n]=nodes[i].v;
cost[n]=nodes[i].c;
num[n]=1;
}
} //递推输出
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
MULTIPLY_PACK(cost[i],val[i],num[i]);
printf("%d\n",dp[m]);
}
return 0;
}
HDU 3732 Ahui Writes Word(多重背包)的更多相关文章
- HDU 3732 Ahui Writes Word 多重背包优化01背包
题目大意:有n个单词,m的耐心,每个单词有一定的价值,以及学习这个单词所消耗的耐心,耐心消耗完则,无法学习.问能学到的单词的最大价值为多少. 题目思路:很明显的01背包,但如果按常规的方法解决时间复杂 ...
- hdoj 3732 Ahui Writes Word (多重背包)
之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!! 然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小. 时隔多日,回过头来看这道题,依旧毫无头绪....不过相比之前 ...
- hdu 3732 Ahui Writes Word
这是一道背包题,当你题读完了的时候,你会觉得这道题明明就是01背包的完全版吗! no no no no no no no no no no no~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- 3732 Ahui Writes Word
// N个物品 放进容量为C的背包里面 要求价值最大// 一看 第一反应是0 1背包 不过 N=100000 C=10000// 注意到 v,c在 10以内// 那么 最多就100种组合了 然后就转化 ...
- 【HDOJ】3732 Ahui Writes Word
初看01背包,果断TLE.是因为n和C都比较大.但是vi和ci却很小,转化为多重背包. #include <cstdio> #include <cstring> ][]; ]; ...
- Ahui Writes Word
Ahui Writes Word Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- HDU 2082 找单词 (多重背包)
题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...
- HDU 5445 Food Problem(多重背包+二进制优化)
http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 ...
- HDU 2844 二进制优化的多重背包
Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
随机推荐
- 网站开发只需数小时?Meteor 说这才是未来
原文: http://www.geekpark.net/topics/211573/ 那个想要挑战过去数十年沿用至今的网站开发模式的新势力来了. Meteor 是从 YC 孵化而出的现代网站开发平台, ...
- 将log4j2的配置文件log4j2.xml拆分成多个xml文件
在日常的项目开发中,我们可能会使用log4j2分离系统日志与业务日志 ,这样一来,log4j2.xml 这个配置文件可能就会变得非常臃肿.庞大,那么我们可以将这个文件拆分成多个配置文件吗? 答案是肯定 ...
- android的百度地图开发(二) 定位
参考:http://blog.csdn.net/mr_wzc/article/details/51590485 第一步,初始化LocationClient类 //获取地图控件引用 mMapView = ...
- 常用Mysql查询语句
1.查询数据表中重复记录 select user_name,count(*) as count from user_table group by user_name having count>1 ...
- csu1811(树上启发式合并)
csu1811 题意 给定一棵树,每个节点有颜色,每次仅删掉第 \(i\) 条边 \((a_i, b_i)\) ,得到两颗树,问两颗树节点的颜色集合的交集. 分析 转化一下,即所求答案为每次删掉 \( ...
- Sharepoint 查阅项字段和计算值字段的定义
查阅项字段定义 <Field Type="Lookup" DisplayName="test2" Required="FALSE" E ...
- hdu 1425 Happy 2004
题目链接 hdu 1425 Happy 2004 题解 题目大意: 求 \[\sum_{d|2004^{x}}d\ mod\ 29\] 记为\(s(2004^x)\) \(sum(2004^{x})= ...
- skywalking学习
skywalking简介 SkyWalking一个开源可观测性平台,用于收集.分析.聚合和可视化来自服务和云原生基础设施的数据.SkyWalking提供了一种简单的方法,可以让你清晰的查看分布式系统. ...
- Oracle PL/SQL入门之慨述
Oracle PL/SQL入门之慨述 一.PL/SQL出现的目的 结构化查询语言(Structured Query Language,简称SQL)是用来访问关系型数据库一种通用语言,它属于第四代语言( ...
- Android Developer -- Bluetooth篇 概述
Bluetooth 安卓平台支持蓝牙网络协议栈,它允许设备与其他蓝牙设备进行无线交换数据.应用程序框架通过安卓蓝牙APIs提供访问蓝牙功能.这些APIs使应用程序通过无线连接到其他蓝牙设备,使点对点和 ...