IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> CF1657D:D. For Gamers. By Gamers.(dp,调和级数,二分) -> 正文阅读

[数据结构与算法]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]);
	//大的花费显然可以从小的花费转移最大攻击力过来
  • 可以发现我们的 cost 数组是单调递增的,所以可以结合二分优化搜索的过程。只需要搜索第一个攻击力严格大于 HD 的位置即可,此位置的花费必定最小,如果找不到代表杀不死。

C o d e : Code: Code:

#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;
}
/*
*/
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:31:56  更:2022-04-27 11:32:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:59:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码