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. android.useDeprecatedNdk=true

    android.useDeprecatedNdk=true ndk{ moduleName "aa" abiFilter "armeabi-v7a" }

  2. app:compileDebugNdk,NDK

    Error:Execution failed for task ':app:compileDebugNdk'. > Error: Your project contains C++ files ...

  3. Selenium2+python自动化19-单选框和复选框(radiobox、checkbox)【转载】

    本篇主要介绍单选框和复选框的操作 一.认识单选框和复选框 1.先认清楚单选框和复选框长什么样 2.各位小伙伴看清楚哦,上面的单选框是圆的:下图复选框是方的,这个是业界的标准,要是开发小伙伴把图标弄错了 ...

  4. vue.js 2的表单控件

    静下心,抄一段sample,以后可以快点到这里来抄...: <!DOCTYPE html> <html> <head> <meta charset=" ...

  5. Android studio配置使debug签名和release签名一致

    在module的build.gradle中添加 android { //重要部分 signingConfigs { release { keyAlias 'jxt' keyPassword '1234 ...

  6. [BZOJ2038] [2009国家集训队]小Z的袜子(hose) 莫队算法练习

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 10299  Solved: 4685[Sub ...

  7. 允许root用户登录ssh

    使用普通用户登录Ubuntu系统,打开命令行窗口 更改root用户密码,命令:sudo passwd root 首先输入当前用户的密码 然后输入root账户的密码 确认root用户的密码 编辑ssh的 ...

  8. POJ 2836 Rectangular Covering(状压DP)

    [题目链接] http://poj.org/problem?id=2836 [题目大意] 给出二维平面的一些点,现在用一些非零矩阵把它们都包起来, 要求这些矩阵的面积和最小,求这个面积和 [题解] 我 ...

  9. stage 3d学习笔记

    1. texture不能实例化,要创建一个texture对象,需要调用Context3D实例的createTexture(width:int, height:int, format:String, o ...

  10. sql server 2008 R2 数据库文件大小限制

    select @@version SQL2005 分五个版本,如下所列: 1.Enterprise(企业版) 2.Development(开发版) 3.Workgroup,(工作群版) 4.Stand ...