首页 > 其他分享 >「刷题记录」 [SHOI2002] 百事世界杯之旅

「刷题记录」 [SHOI2002] 百事世界杯之旅

时间:2023-08-29 10:45:04浏览次数:37  
标签:right get dfrac times 百事 res left SHOI2002 刷题

第一道有关极限期望的数学题,记录一下。

我们设 \(f_i\) 是凑齐前 \(i\) 个球星期望需要买的饮料数。

\[E = 1 \times \dfrac{n - i}{n} + 2 \times \dfrac{i}{n} \times \dfrac{n - i}{n} + 3 \times \left ( \dfrac{i}{n} \right ) ^ 2 \times \dfrac{n - i}{n} + 4 \times \left ( \dfrac{i}{n} \right ) ^ 3 \times \dfrac{n - i}{n} \dots + k \times \left( \dfrac{i}{n} \right ) ^ {k - 1} \times \dfrac{n - i}{n} \]

其中 \(k\) 是一个极大数,可以看作是无限,我们由此可以推出下面的式子:

\[\dfrac{i}{n} E = \dfrac{i}{n} \times \dfrac{n - i}{n} + 2 \times \left ( \dfrac{i}{n} \right ) ^ 2 \times \dfrac{n - i}{n} + 3 \times \left ( \dfrac{i}{n} \right ) ^ 3 \times \dfrac{n - i}{n} + 4 \times \left ( \dfrac{i}{n} \right ) ^ 4 \times \dfrac{n - i}{n} \dots + k \times \left( \dfrac{i}{n} \right ) ^ {k} \times \dfrac{n - i}{n} \]

相减得:

\[\dfrac{n - i}{n} E = \dfrac{n - i}{n} + \dfrac{i}{n} \cdot \dfrac{n - i}{n} + \left ( \dfrac{i}{n} \right ) ^ 2 \cdot \dfrac{n - i}{n} + \dots + \left ( \dfrac{i}{n} \right ) ^ {k - 1} \cdot \dfrac{n - i}{n} - k \cdot \left ( \dfrac{i}{n} \right ) ^ k \cdot \dfrac{n - i}{n} \]

由于 \(k\) 为无限大,所以 \(k \cdot \left ( \dfrac{i}{n} \right ) ^ k \cdot \dfrac{n - i}{n}\) 就无限接近于 \(0\),所以它对答案的影响也无限接近于 \(0\),我们可以直接将其省略,那么期望式子就变成这样了:

\[\dfrac{n - i}{n} E = \dfrac{n - i}{n} + \dfrac{i}{n} \cdot \dfrac{n - i}{n} + \left ( \dfrac{i}{n} \right ) ^ 2 \cdot \dfrac{n - i}{n} + \dots + \left ( \dfrac{i}{n} \right ) ^ {k - 1} \cdot \dfrac{n - i}{n} \]

将系数化为 \(1\) 得:

\[E = 1 + \dfrac{i}{n} + \left ( \dfrac{i}{n} \right ) ^ 2 + \dots + \left ( \dfrac{i}{n} \right ) ^ {k - 1} \]

这里我们可以用等比数列求和公式来做。设 \(S = \dfrac{i}{n} + \left ( \dfrac{i}{n} \right ) ^ 2 + \dots + \left ( \dfrac{i}{n} \right ) ^ {k - 1}\),则 \(\dfrac{i}{n} S = \left ( \dfrac{i}{n} \right ) ^ 2 + \left ( \dfrac{i}{n} \right ) ^ 3 + \dots + \left ( \dfrac{i}{n} \right ) ^ {k}\)

\[\dfrac{n - i}{n} S = S - \dfrac{i}{n} S = \dfrac{i}{n} - \left ( \dfrac{i}{n} \right ) ^ {k} \]

还是考虑极限,\(k\) 为无限大,则 \(\left ( \dfrac{i}{n} \right ) ^ {k}\) 无限接近于 \(0\),都答案的影响可以忽略不计,所以,

\[\dfrac{n - i}{n} S \approx \dfrac{i}{n}\\ S \approx \dfrac{i}{n - i}\\ E = 1 + S = \dfrac{n}{n - i}\\ \]

求出了期望,我们可以写出递推式:\(f_{i + 1} = f_i + \dfrac{n}{n - i}\),转化一下,就是 \(f_i = f_{i - 1} + \dfrac{n}{n - (i - 1)}\)。

现在,我们可以一步一步的递推过去,也可以将 \(f_i\) 的式子拆开,最后得到 \(f_n = \dfrac{n}{n} + \dfrac{n}{n - 1} + \dots + \dfrac{n}{1} = n \times (\dfrac{1}{1} + \dfrac{1}{2} + \dfrac{1}{3} + \dfrac{1}{4} + \dfrac{1}{5} + \dots + \dfrac{1}{n})\),两种方法都可以。

//The code was written by yifan, and yifan is neutral!!!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))

template<typename T>
inline T read() {
    T x = 0;
    bool fg = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        fg |= (ch == '-');
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return fg ? ~x + 1 : x;
}

using fs = tuple<ll, ll>;

int n;

ll gcd(ll x, ll y) {
    if (y == 0) {
        return x;
    }
    return gcd(y, x % y);
}

fs operator+ (const fs& a, const fs& b) {
    ll g = gcd(get<1>(a), get<1>(b));
    ll lcm = get<1>(a) / g * get<1>(b);
    ll fza = get<0>(a), fzb = get<0>(b);
    fza *= (lcm / get<1>(a));
    fzb *= (lcm / get<1>(b));
    return fs(fza + fzb, lcm);
}

int main() {
    n = read<int>();
    fs res = fs(1, 1);
    rep (i, 2, n, 1) {
        res = res + fs(1, i);
    }
    res = fs(get<0>(res) * n, get<1>(res));
    ll num = get<0>(res) / get<1>(res);
    if (get<0>(res) % get<1>(res) == 0) {
        cout << num << '\n';
        return 0;
    }
    res = fs(get<0>(res) % get<1>(res), get<1>(res));
    int digitfz = 0, digitfm = 0, digitps = 0;
    ll tmpfz = get<0>(res), tmpfm = get<1>(res), tmpps = num;
    ll gc = gcd(tmpfz, tmpfm);
    res = fs(get<0>(res) / gc, get<1>(res) / gc);
    tmpfz = get<0>(res), tmpfm = get<1>(res), tmpps = num;
    while (tmpfz) {
        tmpfz /= 10;
        ++ digitfz;
    }
    while (tmpfm) {
        tmpfm /= 10;
        ++ digitfm;
    }
    while (tmpps) {
        tmpps /= 10;
        ++ digitps;
    }
    int maxx = max(digitfz, digitfm);
    rep (i, 1, digitps, 1) {
        cout << ' ';
    }
    cout << get<0>(res) << '\n';
    cout << num;
    rep (i, 1, maxx, 1) {
        cout << '-';
    }
    putchar('\n');
    rep (i, 1, digitps, 1) {
        cout << ' ';
    }
    cout << get<1>(res) << '\n';
    return 0;
}

标签:right,get,dfrac,times,百事,res,left,SHOI2002,刷题
From: https://www.cnblogs.com/yifan0305/p/17663968.html

相关文章

  • SQL刷题小计
    SQL刷题小计确定哪些订单购买了prod_id为BR01的产品(2)这个题可以采用子查询和联合查询子查询#先在第一张表当中查询出id为BRO1的数据然后再将这个数据放在第二张表当中查询selectorder_numfromorderitemswhereprod_id='BR01';selectcust_id,order_datefromOrd......
  • 前端歌谣的刷题之路-第五题-自定义列表
     目录前言题目核心代码总结前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的一天人生难免坎坷大不了从头再来歌谣的意志是永恒的放弃很容易但是坚持一定很酷本题目源自于牛客网题......
  • 前端歌谣的刷题之路-第六题-加粗文字
     目录前言题目核心代码编辑运行结果前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的一天人生难免坎坷大不了从头再来歌谣的意志是永恒的放弃很容易但是坚持一定很酷本题目源自于......
  • [算法学习笔记][刷题笔记] 单调队列优化 dp
    前置知识·单调队列单调队列顾名思义,一般用于解决滑动RMQ问题。它的原理非常简单。我们维护一个双端队列,这个双端队列只维护可能成为区间最值的元素。最基础的单调队列,例如滑动窗口。直接依据题意维护即可。这里提供单调队列模板(STLdeque版)单调队列模板(STLdeque版)......
  • [刷题记录Day22]Leetcode二叉树
    No.1题目二叉搜索树的最近公共祖先思路递归法BST特性如何利用?在BST中,公共祖先一定在p、q数值范围的中间利用BST特性定向搜索注意递归遍历一条边和遍历整棵树的写法不同递归分析返回值:节点,参数:当前节点,p,q终止逻辑:发现当前节点为空,则直接返回当前节点;为什么不用判断p......
  • C/C++百日刷题第三天
    一、选择题1.1、如下代码输出的是什么()chara=101;intsum=200;a+=27;sum+=a;printf("%d\n",sum);A:327B:99C:328D:72题解:这题考察对常见数据结构存储的理解,容易出错在a+=27这个地方,char类型的数据存储范围为-128--127,当a+27之后会超过数据存储范围,a就变为-128,sum加......
  • [算法学习笔记][刷题笔记] 2023/8/26&8/27 解题报告状压 dp
    题单状压dp状压dp是一种非常暴力的算法,它直接记录不同的状态,通过状态进行转移。状压dp可以解决NP类问题。它的原理是暴力枚举每一种可能的状态。所以它的复杂度是指数级的。只能求解小范围的问题。关于记录状态:状压dp通过一个二进制串来记录状态。显然二进制串可以转......
  • [刷题记录Day14]Leetcode二叉树
    No.1题目前序遍历思路递归法代码publicvoidTraverse(TreeNodenode,List<Integer>list){if(node==null)return;list.add(node.val);//中Traverse(node.left,list);//左Traverse(node.right,list);//右}p......
  • [刷题记录Day15]Leetcode二叉树
    No.1题目二叉树的层序遍历思路使用队列关键点:1.每进入一层,层内的节点都被处理完成2.开始遍历层内的节点前,必须先记录该层的节点数量,不能访问到下一层的节点代码publicList<List<Integer>>levelOrder(TreeNoderoot){Queue<TreeNode>queue=newLinkedList......
  • [刷题记录Day17]Leetcode二叉树
    No.1题目平衡二叉树思路递归法在遍历中比较左右子树的高度差递归分析参数:当前传入节点。返回值:以当前传入节点为根节点的树的高度那么如何标记左右子树是否差值大于1呢?可以返回-1来标记已经不符合平衡树的规则了明确终止条件:递归的过程中依然是遇到空节点了为终止,返......