题意:有n种糖果,m种箱子,需要的能量为p。每种糖果有它的能量、体积、数量,每种箱子有它的容量、价格、数量,问至少获得p能量的前提下,最少花多少钱

思路:首先可以知道这是一个背包,然后可以求出能量为i的时候最小的体积。如果箱子也这么做的话会超时,因为求出的最小的体积会很大,所以背包空间太大。题目中给出最终的金额不超过50000,所以可以求出当前金额能获得的最大体积,这样扫一遍就知道结果了。

多重背包:这里使用了单调队列优化多重背包,优化掉了二进制多重背包的log。

单调队列优化背包:详见:《浅谈几类背包题》

然后说下自己的理解:F[j*v+d]-j*w,对于放进单调队列中的这个key值我开始很不理解-j*w是个什么东西,后来理解了发现很巧妙。

对于每个j,先把现在j对应的体积(j*v+d)放进单调队列,然后再更新dp[j*v+d],实际上就是用i-1的结果来更新i。

对于-j*w,假设当前单调队列在j的时候处理完毕,队列首的元素为j',所以就要用j'的key值更新j,j'和j之间的值其实就是相差(j-j')*w,也就是j*w-j'*w,这两项就是论文中加上和减去的那两项。

//唉,弱逼看了好久才懂T T

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
struct Node {int val,cost,num;
}na[210];
int dp[50500];
struct QQ{int j,key;
}qq[510000];
void mul_bag_min(int n,int C){memset(dp,inf,sizeof(dp));dp[0] = 0;for(int i = 0;i < n;i ++){int val = na[i].val,cost = na[i].cost,num = na[i].num;for(int d = 0;d < val;d ++){int head = 0,tail = -1;int siz = (C-d)/val;for(int j = 0;j <= siz;j ++){int vv = j*val+d;int key = dp[vv] - j*cost;while(tail >= head&&qq[tail].key >= key)tail --;qq[++tail] = (QQ){j,key};while(tail >= head&&qq[head].j + num < j)head ++;dp[vv] = min(dp[vv],qq[head].key + j*cost);//cout<<vv<<' '<<dp[vv]<<endl;}}}
}
void mul_bag_max(int n,int C){memset(dp,0,sizeof(dp));for(int i = 0;i < n;i ++){int val = na[i].val,cost = na[i].cost,num = na[i].num;for(int d = 0;d < val;d ++){int head = 0,tail = -1;int siz = (C-d)/val;for(int j = 0;j <= siz;j ++){int vv = j*val+d;int key = dp[vv] - j*cost;while(tail >= head&&qq[tail].key <= key)tail --;qq[++tail] = (QQ){j,key};while(tail >= head&&qq[head].j + num < j)head ++;dp[vv] = max(dp[vv],qq[head].key + j*cost);//cout<<vv<<' '<<dp[vv]<<endl;}}}
}
int main(){int T;scanf("%d",&T);while(T --){int n,m,p;scanf("%d%d%d",&n,&m,&p);for(int i = 0;i < n;i ++){scanf("%d%d%d",&na[i].val,&na[i].cost,&na[i].num);}mul_bag_min(n,p+150);int mina = inf;for(int i = p;i < p+150;i ++){mina = min(mina,dp[i]);}if(mina == inf){puts("TAT");continue;}for(int i = 0;i < m;i ++){scanf("%d%d%d",&na[i].cost,&na[i].val,&na[i].num);}mul_bag_max(m,50000);int ans = inf;for(int i = 0;i <= 50000;i ++){if(dp[i] >= mina){ans = i;break;}}if(ans > 50000)puts("TAT");else cout<<ans<<endl;}return 0;
}

HDU 5445 Food Problem相关推荐

  1. [HDU 5445]Food Problem[多重背包]

    题目链接:[HDU 5445]Food Problem[多重背包] 题意分析: 有n种类型的点心,每种提供t的能量,占据u的空间,有v个: 有m种类型的卡车,每种容量x,雇佣花费y,能提供z辆: 点心 ...

  2. HDU 5445:Food Problem

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5445 题目翻译: 有N种甜点,M种卡车,至少需要P点能量. 然后给出N个 t, u, v,t是甜点能提 ...

  3. hdu 5445 Food Problem (多重背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5445 题解:一看就像多重背包就是怎么看都不好做.但是这里有点明显的就是有两个背包,一个是糖 ...

  4. HDU 5445 Food Problem 多重背包+二进制优化

    据说也可以用单调队列优化多重背包,但是我不会,所以还是选择了二进制优化... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:先给n,m, ...

  5. HDU 5445 Food Problem 两次多重背包

    题目描述: Problem Description Few days before a game of orienteering, Bell came to a mathematician to so ...

  6. HDU 5445 Food Problem(多重背包)

    Description n种点心,每种点心有一定的能量t,体积u和数量v,现在要用m种卡车搬运这些点心,每种开车有一定的容量x,花费y和数量z,点心可以分割但选一块就要都选,现在问将运送总能量不小于p ...

  7. Hdu 5445 Food Problem 多重背包

    题意:给出n,m,p,分别表示有n种点心,m种卡车,能量p. 然后给出每种点心所能获得的能量,所占卡车的体积,以及每种点心的数量. 再给出每种卡车所能装下的空间,租这种卡车的费用,以及每种卡车的数量. ...

  8. hdu A + B Problem II(大数相加,数组实现)

    hdu A + B Problem II(大数相加,数组实现) 题目走起 注意最后一个case 不需要换行 下面代码 #include<stdio.h> #include<strin ...

  9. HDU.1001 Sum Problem

    原题 HDU.1001 Sum Problem 分类 杂题 题意 计算从1到正整数n的累加和. 输入/输出 要求与格式 输入内容 每行输入一个正整数 输出结果 结果为累加和 输出格式 每个输出结果独占 ...

最新文章

  1. 阻塞 、非阻塞;同步、异步
  2. 深度学习进行目标识别的资源列表
  3. mac/unix系统:C++实现一个端口扫描器
  4. Lucene之样例解析(1)-配置Lucene的源代码
  5. 前后端交互之封装Ajax+SpringMVC源码分析
  6. 注册app短信验证平台_怎样挑选网站验证码短信平台?
  7. 学习 ASP.NET MVC (第五回)理论篇
  8. C语言·数组·密码编译(阿斯克码法)
  9. 【第157期】游戏策划:给@Archer的简历分析
  10. 品质体系及标准大集合(偏向软件)
  11. mysql innodb 唯一键里的字段为什么不能为NULL
  12. R语言数据的排序、转换、汇总
  13. 图像处理-HSV和RGB相互转换
  14. Delphi报表开发ReportMachine的小计和总计的计算
  15. 蓝桥杯:约数个数(C++)
  16. python常胜将军问题_蓝奏云盘pc版(lanzou-gui)更新0.3.3
  17. 咕泡p6java架构师五期涨薪班
  18. PWM整流器仿真模型 单位功率因数 matlab simulink
  19. rk3188--4.android用initrd文件系统启动流程
  20. 以太坊存储Swarm的开发指南

热门文章

  1. 计算机可以玩游戏吗教程,怎么在电脑上玩ios游戏_电脑上玩ios游戏教程_飞翔教程...
  2. 存储基础:ATA、SATA、SCSI、SAS、FC
  3. 计算机打印设置方法,针式打印机怎么设置【图文详解】
  4. 编程学不进去?如何才能拯救你的编程能力?
  5. 固有频率约束下桁架优化的动态算术优化算法(Matlab代码实现)
  6. 从人肉跑数机到真数据分析,中间隔着沟通能力
  7. Dew Lab Studio 2020 VCL软件包,很好的RAD(快速软件开发)工具
  8. PLATFORMS(平台)
  9. The type java.lang.Object cannot be resolved It is indirectly referenced ... .
  10. bids格式数据中config文件的编写