国王游戏(算法竞赛进阶指南 P40,贪心 + 大数乘除)

114. 国王游戏 题意: 除第一个人以外的每个人能获得的奖赏为他之前所有人的左手乘积除以自己右手上的值(注意是之前的所有人不包括自己),通过改变顺序使得获得最多奖赏最小化。 思路: 贪心策略:受到奶牛的杂技这题的影响,我们发现乘积越大的要往后放除的大的也要往后放,所以我们根据左手右手的乘积从小到大排序,然后以此计算取max即可,交了之后WA了,标准答案贼大已经超出ull范围,所以还得上个高精乘除单精(顺便复习一手)。 AC代码: #include<bits/stdc++.h> using namespace s. 阅读详情

一.题目链接:

国王游戏

二.题目大意:

国王和大臣排队,国王始终排在最前面.

每个人的左右手里各有一个数 a,b.

每 i 位大臣获得钱数为  \frac{1}{b[i]} \prod_{j = 0}^{i - 1}a[j]

现在对大臣重新排队,求最小化最大大臣金额.

三.分析:

按照大臣的 a * b 排序,得到的最大大臣金额是最小的.

证明:

这里选用临项交换的方法.

设第 i 位大臣的 a 为 a[i], b 为 b[i]

第 i + 1 位大臣的 a 为 a[i + 1], b 为 b[i + 1]

则,交换前两位大臣的金额分别为 \frac{1}{b[i]} \prod_{j = 0}^{i - 1}a[j] 和 \frac{1}{b[i + 1]} \prod_{j = 0}^{i}a[j]

交换后的金额分别为 \frac{1}{b[i + 1]} \prod_{j = 0}^{i - 1}a[j] 和 \frac{a[i + 1]}{b[i]} \prod_{j = 0}^{i - 1}a[j]

提出公因项  \prod_{j = 0}^{i - 1}a[j] 

得:\frac{1}{b[i]} 和 \frac{a[i]}{b[i + 1]}

\frac{1}{b[i + 1]} 和 \frac{a[i + 1]}{b[i]}

现在来比较交换前后最大的金额

即:max(\frac{1}{b[i]}, \frac{a[i]}{b[i + 1]}) 与 max(\frac{1}{b[i + 1]}, \frac{a[i +1]}{b[i]})

两遍同乘以 b[i]b[i+1] 

转化为:max(b[i+1], a[i]b[i]) 与  max(b[i], a[i+1]b[i+1])

若 a[i]b[i] \geq a[i+1]b[i+1]

又因为 a[i]b[i] \geq a[i]

所以 max(b[i+1], a[i]b[i]) \geq max(b[i], a[i+1]b[i+1])

反之若 a[i+1]b[i+1] \geq a[i]b[i]

又因为 a[i+1]b[i+1] \geq b[i+1]

所以 max(b[i], a[i+1]b[i+1])\geq max(b[i+1], a[i]b[i])

综上所得:当 a[i]b[i] \geq a[i+1]b[i+1] 时,交换后更优,反之交换前更优.

因此,将大臣按照 a[i]b[i] 排序后,此时即可取得最小的金额.

证毕.

之后遍历一遍,取最大值即可.

ps:这里要手写大数乘除法(顺便留个模板).

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)5e3;
const ll mod = 998244353;
const int inf = 0x3f3f3f3f;

struct node
{
    int a, b;
}s[M + 5];

bool cmp(node x, node y)
{
    return x.a * x.b < y.a * y.b;
}

int product_len, quot_len, ans_len;
int product[M + 5], quot[M + 5], ans[M + 5];

void mul(int x)
{
    for(int i = 1; i <= product_len; ++i)
        product[i] *= x;
    product_len += 4;
    for(int i = 1; i <= product_len; ++i)
    {
        product[i + 1] += product[i] / 10;
        product[i] %= 10;
    }
    while(!product[product_len])
        product_len--;
}

void div(int x)
{
    int rem = 0;
    bool flag = 1;
    for(int i = product_len; i; --i)
    {
        rem = rem * 10 + product[i];
        quot[i] = rem / x;
        rem %= x;
        if(quot[i] && flag)
        {
            flag = 0;
            quot_len = i;
        }
    }
}

bool bigger()
{
    if(quot_len != ans_len)
        return quot_len > ans_len;
    for(int i = ans_len; i; --i)
    {
        if(quot[i] != ans[i])
            return quot[i] > ans[i];
    }
    return 0;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i <= n; ++i)
        scanf("%d %d", &s[i].a, &s[i].b);
    sort(s + 1, s + n + 1, cmp);
    product[++product_len] = 1;
    mul(s[0].a);
    for(int i = 1; i <= n; ++i)
    {
        div(s[i].b);
        if(bigger())
        {
            ans_len = quot_len;
            memcpy(ans, quot, sizeof(quot));
        }
        mul(s[i].a);
    }
    for(int i = ans_len; i; --i)
        printf("%d", ans[i]);
    printf("\n");
    return 0;
}

 

国王游戏【贪心算法】 /***************************************** 备注: ******************************************/ #include <queue> #include <math.h> #include <stack> #include <stdio.h> #include <iostream> #include <vector> #include <iomanip 阅读详情

相关推荐

P1080 [NOIP2012 提高组] 国王游戏题解

排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。数组,因为直接看整体,很难做,那么我们可以从两个人中找出规律,再依次循环下去。的人放在前面,把下标为。

wangzihan1026的博客 618

算法笔记:国王游戏

恰逢H 国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前

qq_74351198的博客 1645

如何在Ubuntu 22.04上为AlphaFold3配置NVIDIA A100 GPU(含驱动安装避坑指南)

本文提供了在Ubuntu 22.04系统上为AlphaFold3部署NVIDIA A100 GPU的完整安装教程。内容涵盖从系统环境准备、NVIDIA驱动安装与避坑指南,到Docker容器化部署、数据库获取以及最终构建运行AlphaFold3的详细步骤,旨在帮助研究者和开发者高效配置高性能计算环境,充分发挥A100的硬件潜力。

nft7creator的博客 468

国王游戏——c++实现

题目描述 ​ 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。 ​ 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的

杰之行的博客 4416

(MIUI)小米手机录音文件深度寻踪:从系统缓存到数据目录的实战解析

本文深入解析了MIUI系统中录音文件丢失的常见原因及解决方案,包括系统升级兼容性问题、应用缓存机制异常和存储权限变动。通过实战操作指南,详细介绍了如何从系统目录、数据库层面恢复录音文件,并提供了预防措施和自动化备份方案,帮助小米手机用户有效找回重要录音数据。

weixin_42699679的博客 518

ROS-Industrial :simple_message

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录1. 概述2. 协议(Protocol)3. HEADER解析3.1 MSG_TYPE3.2 COMM_TYPE3.3 REPLY CODE 1. 概述 Simple_Message是ROS-Industrial的一部分,定义了用于与工业机器人控制器通信的简单消息连接协议。另外还包括处理连接受限系统的处理器和管理器类。 2. 协议(Protocol) 简单消息(simplemessage)协议定义了ROS的驱动层和机器人控制器之.

flsxyw的博客 780

贪心算法:国王游戏

然后左边的s/R【i】是一定比s*L【i+1】/R【i】小的,那么就能得到左边式子里s*L【i】/R【i+1】是比较大的,再把他们两个取出来得到s*l【i】/R【i+1】<s*L【i+1】/R【i】,两边同时除s,得到。l【i】/R【i+1】<L【i+1】/R【i】,两边同乘R【i】*R【i+1】得到L【i】*R【i】<L【i+1】*R【i+1】,所以就推出了将L【i】*R【i】当作排序方法,使得这个值越小排在越前面。写的时候就想到高精度除低精度了,用的还是高精度乘高精度的板子。

chkQAQ的博客 483

WSL2部署Cadence Virtuoso IC25.1:Ubuntu 26.04排障实录

WSL2以轻量虚拟机结合完整Linux内核,为Windows桌面环境提供了原生级Linux运行能力,解决了传统虚拟机资源开销大、双系统切换低效的问题。对于依赖X11图形协议、FlexNet许可服务和特定动态库的EDA工具链而言,利用WSL2部署Linux发行版需要关注系统集成、显示通路与许可连通性。从技术原理看,图形层X Server的配置、动态库依赖的补齐以及license服务的主机名解析,共同构成EDA工具在WSL2中稳定运行的关键环节。在芯片设计场景中,设计工程师常需在Windows办公机与Linux

weixin_29597551的博客 211

[NOIP2012 提高组] 国王游戏(C++,贪心,高精度)

贪心条件推导完成后,只需要再写一个高精度就可以了

m0_74036684的博客 1904

使用RepeatModeler和RepeatMasker注释基因组重复序列

重复序列注释有两种常用策略,基于同源序列相似性和基于重复序列结构特征。RepeatMasker是基于同源序列相似性注释序列的常用工具, RepeatModeler可用来从头对基因组的重复序列家族进行建模注释,它的核心组件是RECON和RepatScout。 这篇教程介绍如何使用RepeatModeler从头鉴定基因组的重复序列,之后用RepeatMasker根据自...

xuzhougeng blog 8852

ANSYS——模态分析的理论基础

ANSYS模态分析理论基础

python_AI_fans的博客 9081

P1080 国王游戏(贪心+大数乘除)

首先要贪心。其次要大数。 贪心简单证明是:先只有两个大臣,他们位置交换得出两个值。然后用数学方法证明。(数学太弱了) 当时只想到贪心,交了,wa了5个数据。还是不明所以。 后来翻博客,又看了一边题。才知道了左手乘积可能达到10的4000次方。

k的博客 284

C# 从数秒到毫秒:MySQL+Redis百万数据优化实战全解析

在处理百万级数据时,传统单体数据库常面临查询效率低下、数据库负载过高和用户体验差等问题。为解决这些性能瓶颈,可以采用MySQL分库分表、Redis缓存和异步统计的组合策略。 数据库分片:通过水平分表和分库实现,将单表数据分散到多个物理表或数据库实例中,降低单点负载。 Redis缓存:利用Redis缓存高频数据,减少数据库查询压力,提升响应速度。 异步统计:通过消息队列(如RabbitMQ)解耦统计任务,后台处理非实时任务,避免阻塞主流程。 这些优化策略能够显著提升系统性能,确保在高并发和大数据量场景下的稳定

墨夶的博客 852

???[NOIP2012]国王的游戏(列式子排序贪心,高精度乘除)

排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。我们发现,i大臣和j大臣交换位置并不影响其他大臣的金币数,只会改变i大臣和j大臣的金币数。我们假设i大臣排在j大臣前面,那么分别可以得出两个式子,i大臣的金币数和j大臣的金币数。最后一名大臣获得的金币数就是最多的。国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。

2301_80718054的博客 525

1、使用Spark SQL查询Databricks:全面指南

本博客全面介绍了如何使用Spark SQL在Databricks平台上进行高效的数据查询与分析。内容涵盖SQL基础操作、数据过滤、复杂查询技巧、简单与高级计算、数据聚合、日期处理等核心主题,适合数据分析师、开发人员及SQL学习者。通过逐步讲解和实用示例,帮助读者掌握从入门到高级的SQL技能,并提供学习路径建议和免费代码资源,助力实际数据分析工作。

redis7keeper的博客 90

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

贪心算法——国王游戏(洛谷P1080)

贪心算法——国王游戏1、题目描述2、问题分析3、算法源码 1、题目描述 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他...

weixin_43715601的博客 7865

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

P1080 国王游戏(c++)

题目: 题意:找出获得最高赏金的大臣 每一个大臣获得的赏金=国王的左手 *前面所有大臣的左手乘积/自己的右手 于是这里可以自然的想到贪心:尽可能让前面所有人的乘积更小,而自己的右手又尽可能地大,让每一个都这么排序后,找出其中获得最高赏金的大臣 (由于本题需要使用高精度,我这里使用了c++的重载运算符) 贪心思想:借用以下一位大佬的文章 交换论证显然符合这个问题 #include <iostream> #include <algorithm> #include &.

qq12323qweeqwe的博客 5379

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

蓝桥云题库之国王游戏——Python满分解答

国王游戏题目描述输入描述输出描述输入输出样例示例输入示例输出解题思路从推测开始尝试优化排序方法整理思路代码实现 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。 国王不希望某一个大臣获得特别多

zbp_12138的博客 3539

[Daimayuan]新国王游戏(C++,数学)

又到了H国国庆, 国王再次邀请n位大臣来玩有奖游戏。上次国庆被众臣吐槽国王小气后,国王决定今年大方点,改变游戏规则且不再参与游戏,免得被大臣们质疑。首先, 他让每位大臣在左、 右手上面分别写下一个正整数。然后让这n位大臣排成一排。排好队后, 所有的大臣都会获得国王奖赏的若千金币, 每位大臣获得的金币数分别是:排在该大臣后面的所有人的左手上的数的乘积乘以他自己右手上的数。国王希望所有大臣获得的金币数之和最多,所以他想请你帮他重新安排一下队伍的顺序。简而言之,给定n对数ai​bi​。

m0_74036684的博客 923

7-2国王游戏

国王游戏

asasa666的博客 2830

国王游戏

#include<bits/stdc++.h> using namespace std; #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) #define dec(i,l,r) for(int i=l;i>=r;--i) const int power=4,base=10000; template<t...

Lsylzx 770

JAVA小游戏(国王和大臣)

棋规则和需求 规则: 棋子:2颗国王棋和(8+16)颗大臣棋;分别用黑白两色代表国王和大臣(黑子为国王、白子为大臣) 棋盘:5*9的二维棋盘,共37个交点,如图所示: 吃子规则(包括移子和添子): 1、国王每回合可以选择移动一步、或者跳吃大臣一颗棋子,即就是间隔一个大臣棋子跳到对应空位置,大臣棋子被吃掉 2、大臣前16回合只能每次添加一颗棋子,只有将16颗棋子全部都落完后,第17回合才可以移动棋子;或者在落完棋子之前大臣就已经输了就不用移子操作了 胜负规则: 国王不能移动也不能跳吃则判负,大臣赢; 大臣被吃

A5wa41s的博客 3696

国王游戏(贪心 + 高精度乘法 + 高精度除法 + 高精度比较大小)

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。 首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。 然后,让这 n 位大臣排成一排,国王站在队伍的最前面。 排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是: 排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。 国王不希望某一个大臣获...

逐梦er的博客 2243

[NOIP2012] 国王游戏

题意:有一个国王和n个大臣,排成一列玩一个,每个人左右手分别有一个数值,每个人的分值定义为之前所有人左手的分值和除以自己右手的分值(下取整),国王始终站在最前面,现要你安排大臣的顺序,使得分值最大的大臣的分值尽量小 题解: 贪心+高精 按左右手乘积从小到大排序 所有数的乘积最大不超过\(10^{4000}\),码一发高精乘低精和高精除低精即可 注意:比较s和g时写成函数会wa,可能传指针的时候会有...

weixin_33827731的博客 141

国王(C++)

在n×n (1<=n<=10)的棋盘上放k(0<=k<=n×n)个国王(一个国王可以攻击相邻的8个格子),求使他们无法互相攻击的方案总数。输出一行表示方案总数,若不能够放置则输出0。只有一行为两个整数n和k。

qxh10的博客 588
上一篇: Radar Installation(POJ - 1328,贪心)
下一篇: Find the answer (HDU - 6609,权值线段树)
The___Flash
博客等级 码龄8年 79粉丝 223原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值