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(多重背包)的更多相关文章

  1. HDU 3732 Ahui Writes Word 多重背包优化01背包

    题目大意:有n个单词,m的耐心,每个单词有一定的价值,以及学习这个单词所消耗的耐心,耐心消耗完则,无法学习.问能学到的单词的最大价值为多少. 题目思路:很明显的01背包,但如果按常规的方法解决时间复杂 ...

  2. hdoj 3732 Ahui Writes Word (多重背包)

    之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!!  然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小. 时隔多日,回过头来看这道题,依旧毫无头绪....不过相比之前 ...

  3. hdu 3732 Ahui Writes Word

    这是一道背包题,当你题读完了的时候,你会觉得这道题明明就是01背包的完全版吗! no no no no no no  no no  no no no~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  4. 3732 Ahui Writes Word

    // N个物品 放进容量为C的背包里面 要求价值最大// 一看 第一反应是0 1背包 不过 N=100000 C=10000// 注意到 v,c在 10以内// 那么 最多就100种组合了 然后就转化 ...

  5. 【HDOJ】3732 Ahui Writes Word

    初看01背包,果断TLE.是因为n和C都比较大.但是vi和ci却很小,转化为多重背包. #include <cstdio> #include <cstring> ][]; ]; ...

  6. Ahui Writes Word

    Ahui Writes Word Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...

  7. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

  8. HDU 5445 Food Problem(多重背包+二进制优化)

    http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 ...

  9. HDU 2844 二进制优化的多重背包

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

随机推荐

  1. cookie登录

    #coding:utf-8 import tornado.httpserver import tornado.ioloop import tornado.options import tornado. ...

  2. tcpreplay 缓存算法研究

    一.  缓存算法 1.1  算法目的 流量拆分算法的运算会明显影响包的发送速率,为了提高发送速率, tcpreplay 使用了缓存机制,该部分代码也封装在tcpprep工具里,运行 tcpprep ( ...

  3. [Oracle] oracle统计信息

    Oracle统计信息 Oracle数据库里的统计信息可以分为6种类型: 表的统计信息 索引的统计信息 列的统计信息 系统统计信息 数据字典统计信息 内部对象统计信息 图 1: Oracle统计信息 基 ...

  4. windows 2012(64位) IIS配置asp程序 500 - 内部服务器错误。您查找的资源存在问题,因而无法显示。

    在网上找了很久,包括常规的设置父路径之类的,一直都不可以,搞了一晚上毫无成就感,第二天早上无意中看到一篇文章,说到点子上了,非常感谢.源地址已经找不到了,我把大概的问题截图说明一下. 方法如下:1.打 ...

  5. android的百度地图开发(二) 定位

    参考:http://blog.csdn.net/mr_wzc/article/details/51590485 第一步,初始化LocationClient类 //获取地图控件引用 mMapView = ...

  6. Fiddler抓包7-post请求(json)【转载】

    本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/fiddler/ 前言上一篇讲过get请求的参数都在url里,post的请求相对于get ...

  7. 出现函数重载错误call of overloaded ‘printfSth(double)’ is ambiguous

    class C: { public: void printfSth(int i) { cout<<"C::printfSth(int i):"<<i< ...

  8. cmake add_executable 与 include_directories

    在cmake里add_executable里如果没有包含.cpp文件,该.cpp文件就不适用include_directories包含文件

  9. 利用ICSharpCode进行压缩和解压缩

    说说我利用ICSharpCode进行压缩和解压缩的一些自己的一下实践过程 1:组件下载地址 参考文章:C#使用ICSharpCode.SharpZipLib.dll压缩文件夹和文件 2: 文件类 // ...

  10. Ubuntu14.04 在右键中添加 在终端中打开

    1.在terminal中执行: sudo apt-get install nautilus-open-terminal 此时可能会提示:nable to locate package nautilus ...