CF1657D:D. For Gamers. By Gamers.(dp,调和级数,二分)
传送门
- 有 m 场战斗,每场战斗前在 n 种单位中选择一种,使得用拥有的钱招募士兵能打败怪物,同时尽可能少地花费金钱。
- 判定打败怪物的公式是: ∑ ( h i ) / D i > H i / ∑ ( d i ) ∑(hi)/Di > Hi/∑(di) ∑(hi)/Di>Hi/∑(di),即士兵攻击的秒伤 严格大于 怪物攻击的秒伤,士兵死完前必定先杀死怪物。这个公式显然可以移一下项 变成 ∑ ( h i ∗ d i ) > H i ∗ D i ∑(hi*di) > Hi*Di ∑(hi∗di)>Hi∗Di,右边这个东西对于每个怪物是固定的我们定义成 HD。
- 推完公式后就可以开摆了 ,我们从一个全新的角度去维护,定义 cost[i] 为花费 i 金钱能获取的最大攻击力(也就是 ∑ ( h i ∗ d i ) ∑(hi*di) ∑(hi∗di)),如果某个 cost[i] 严格大于了 HD,就代表 i 花费能战胜这个怪物,是一个可行解。
- 花费的范围达到了 1e6,该怎么维护?答案用数学中的调和级数维护我们的 cost :
forr(i, 1, n) {ll a, b, d;cin >> a >> b >> d;c[a] = max(c[a], b * d);//招募一个这种单位,对应的 c[i] 维护一个最大攻击力}//调和级数,虽然是双层但遍历的数量很少for (int i = 1; i <= m; i++)for (int j = 1; i * j <= m; j++) cost[i * j] = max(cost[i * j], c[i] * j);//旧花费可以从之前的 一个单位 * 个数 转移到新的花费,还是维护最大攻击力forr(i, 1, m)cost[i] = max(cost[i], cost[i - 1]);//大的花费显然可以从小的花费转移最大攻击力过来
#include<bits/stdc++.h>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define forr(a,b,c) for(int a=b;a<=c;a++)
#define rfor(a,b,c) for(int a=b;a>=c;a--)
#define all(a) a.begin(),a.end()
#define oper(a) (operator<(const a& ee)const)
#define endl "\n"
using namespace std;typedef long long ll;
typedef pair<int, int> PII;double DNF = 1e17;
const int N = 200010, M = 1000010, MM = 110;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int INF = 0x3f3f3f3f, mod = 1e9 + 7;
int n, m, k, T, S, D, K;
ll cost[M], c[M];void solve() {cin >> n >> m;forr(i, 1, n) {ll a, b, d;cin >> a >> b >> d;c[a] = max(c[a], b * d);}for (int i = 1; i <= m; i++)for (int j = 1; i * j <= m; j++) cost[i * j] = max(cost[i * j], c[i] * j);forr(i, 1, m)cost[i] = max(cost[i], cost[i - 1]);cin >> k;forr(i, 1, k) {ll a, b, mos;cin >> a >> b;mos = a * b;int t = upper_bound(cost + 1, cost + 1 + m, mos) - cost;if (t == m + 1)cout << -1;else cout << t;cout << ' ';}
}int main() {cinios;T = 1;while (T--)solve();return 0;
}
/*
*/
CF1657D:D. For Gamers. By Gamers.(dp,调和级数,二分)相关推荐
- D - For Gamers. By Gamers.
D - For Gamers. By Gamers. 分析: 阅读理解+打表+二分答案(神仙打表) 令我方的伤害和血量分别为 ( a , b ) (a,b) (a,b),敌方为 ( c , d ) ( ...
- D. For Gamers. By Gamers.
调和级数枚举+二分查询. 现在有m只怪兽要杀死,给定n种可选择的士兵,每次选择一种,同种士兵可以选多个.当士兵的攻击力之和大于怪兽的攻击力时,就可以杀死怪兽.每种士兵的雇用价格不一样,请你决定杀死当前 ...
- Average and Median(500)dp,二分 AtCoder Beginner Contest 236
E - Average and Median / Time Limit: 2 sec / Memory Limit: 1024 MB Score : 500 points Problem Statem ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
- HDU 3646 DP + 二分
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3646 题意:你有N把武器,每把武器可以对敌人造成一定的伤害(et:攻击力500,敌人血量为200,杀死敌人 ...
- LeetCode 363. 矩形区域不超过 K 的最大数值和(DP+set二分查找)
1. 题目 给定一个非空二维矩阵 matrix 和一个整数 k,找到这个矩阵内部不大于 k 的最大矩形和. 示例: 输入: matrix = [[1,0,1],[0,-2,3]], k = 2 输出: ...
- HDU 3586 Information Disturbing (树形DP,二分)
题意: 给定一个敌人的通信系统,是一棵树形,每个节点是一个敌人士兵,根节点是commander,叶子是前线,我们的目的是使得敌人的前线无法将消息传到commander,需要切断一些边,切断每条边需要一 ...
- NYOJ-单调递增子序列(二)(dp加二分)
单调递增子序列(二) 描述: 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度. 如:1 9 10 5 11 2 13的最长单调递增 ...
- Codeforces Round #190 (Div. 1): E. Ciel and Gondolas(决策单调性DP+wqs二分)
E. Ciel and Gondolas 题意: bzoj5311:https://www.lydsy.com/JudgeOnline/problem.php?id=5311 同一道题目,但是bzoj ...
最新文章
- c语言 获得回车按键控制输入法,android调用输入软键盘回车键跟删除键
- python新手入门-python新手入门方法
- MySQL删除关联表的数据
- adb 查看当前包名和Activity
- 盖茨比乔布斯_如何使用盖茨比创建您的博客并通过手机进行处理
- 硬核图解| Kafka 如何保证消息不丢失?
- java值传递和引用传递_辨析Java方法参数中的值传递和引用传递
- Java集合框架知多少——干货!!!
- xlc mysql_mysql – 用于存储产品信息的noSQL?
- Atitit 分期理论 attilax总结
- 惠普bios硬重置_惠普重置BIOS
- java电子邮件收发系统的设计与实现_基于Java Mail的电子邮件收发系统的设计与实现毕业论文.doc...
- 计算机系统关机后自动重启,深度技术win7系统电脑关机后又自动开机如何解决【图文】...
- MySQL百万数据插入
- AdMob Mediation
- opencv-11-中值滤波的C++实现与自适应中值滤波
- HDMI转MIPIDSI芯片,东芝TC358870
- Windows下使用pip时出现TSL/SSL错误解决方案
- Vue3 UI组件库对比,Naive UI、Element Plus、 Ant Design Vue
- 中国联通物联网部件服务介绍