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 ...
随机推荐
- (转)vim 常用快捷键 二
转自:http://www.cnblogs.com/wangkangluo1/archive/2012/04/12/2444952.html 键盘移动 (Move) 一切都从键盘的移动 k -> ...
- Video for Linux Two API Specification revision0.24【转】
转自:http://blog.csdn.net/jmq_0000/article/details/7536805#t136 Video for Linux Two API Specification ...
- Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.Exec
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.> com.android.build.api.tr ...
- Mina框架的学习笔记——Android客户端的实现
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...
- android的百度地图开发(一)
1,注册百度开发者账号 2,申请key ,注意开发版SH和发布版的SH 获取开发版SHA1: 输入命令:keytool -list -v -keystore debug.keystore,回车输入 ...
- 牛客练习赛16 C 任意点【并查集/DFS/建图模型】
链接:https://www.nowcoder.com/acm/contest/84/C 来源:牛客网 题目描述 平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可 ...
- (转)代码中实现button
链接地址:http://www.cnblogs.com/hukezhu/p/4500206.html 随着iOS开发发展至今,在UI制作上逐渐分化为了三种主要流派:使用代码手写UI及布局:使用单个xi ...
- HDU 2586 How far away? LCA 转化成RMQ
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...
- jsp登陆
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 操作系统/etc/hosts文件配置
windows对应 C:\Windows\system32\drivers\etc\hosts linux: /etc/hosts Hosts - The static table lookup fo ...