牛客 NC16561 国王的游戏 (经典贪心之 使最大值最小)

题目链接

解题思路:(经典贪心之-----使最大值最小,且因该题的数据范围故应使用高精度乘法,高精度除法)

贪心思路的证明:

假设相邻的两个人左右手分别是(a, b), (A, B)。假设a * b <= A * B,i之前所有人的左手乘积为S。

则,ans1 = max{S / b, S * a / B}
若交换(a,b),(A,B) 的顺序
则,ans2 = max{S / B, S * A / b}
因为,a * b <= A * B
所以,S * a / B <= S * A / b
又因为,S / B <= S * a / B
所以,ans2 = S * A / b
ans1 = max{S / b, S * a / B}
所以,ans1 <= ans2

所以贪心策略应按照每个大臣左右手数字乘积的升序来排列

注:高精度算法

代码:

#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <iterator>
#include<math.h>
#define debug() puts("what the fuck")
#define ll long long
#define INF 0x3f3f3f3f   //无穷大
const int  maxn=8000009;
const double pi = acos(-1.0);  //π的大小
using namespace std;
vector<int> mul(vector<int>a,int b) //高精度乘法
{
    vector<int>c;
    int t=0;
    for(int i=0; i<a.size(); i++)
    {
        t+=a[i]*b;
        c.push_back(t%10);
        t/=10;
    }
    while(t)
    {
        c.push_back(t%10);
        t/=10;
    }
    return c;
}


vector<int>div(vector<int>a,int b) //高精度除法
{
    vector<int> c;
    bool flag=true;
    int t=0;
    for(int i=a.size()-1; i>=0; i--)
    {
        t=t*10+a[i];
        int x=t/b;
        if(!flag||x)
        {
            flag=false;
            c.push_back(x);
        }
        t%=b;
    }
    reverse(c.begin(),c.end());
    return c;
}


vector<int>max_vec(vector<int>a,vector<int>b)
{
    if(a.size()>b.size())
        return a;
    if(a.size()<b.size())
        return b;
    if(vector<int>(a.rbegin(),a.rend())>vector<int>(b.rbegin(),b.rend()))
        return a;
    else
        return b;
}


struct Node
{
    int l,r;
} n[20000];
bool cmp(Node a,Node b)
{
    return a.l*a.r<b.l*b.r;
}
int main()
{
    int p;
    cin>>p;
    for(int i=0; i<=p; i++)
    {
        cin>>n[i].l>>n[i].r;
    }
    sort(n+1,n+1+p,cmp);
    vector<int>a(1,1);
    vector<int>res(1,0);
    for(int i=0; i<=p; i++)
    {
        if(i!=0)
            res=max_vec(res,div(a,n[i].r));
        a=mul(a,n[i].l);
    }
    for(int i=res.size()-1; i>=0; i--)
        cout<<res[i];
    cout<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目要求:给定一个二叉树和一个整数target,找出所有从根节点到叶子节点路径之和等于target的路径。 解题思路:可以使用深度优先搜索(DFS)的方法来解决该问题。首先定义一个辅助函数来进行递归搜索,该辅助函数的参数包括当前节点、当前路径、当前路径的和以及目标和。在搜索过程中,需要维护一个数组来保存当前节点到根节点的路径。搜索过程如下: 1. 如果当前节点为空,则返回。 2. 将当前节点的添加到当前路径中。 3. 将当前节点的累加到当前路径的和中。 4. 如果当前节点是叶子节点,且当前路径的和等于目标和,则将当前路径添加到结果中。 5. 递归地搜索当前节点的左子树和右子树,并传递更新后的当前路径和当前路径的和。 最后,在主函数中调用辅助函数,并返回结果即可。 以下是题目的完整代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def pathSum(root, target): def dfs(node, path, path_sum, target, res): if not node: return path.append(node.val) path_sum += node.val if not node.left and not node.right: # 当前节点是叶子节点 if path_sum == target: res.append(path[:]) # 注意需要复制一份path,否则会出现问题 dfs(node.left, path, path_sum, target, res) dfs(node.right, path, path_sum, target, res) path.pop() # 回溯到父节点,去掉当前节点 path_sum -= node.val res = [] dfs(root, [], 0, target, res) return res ``` 这样就能找出所有满足路径和等于目标和的路径了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值