23.8.15 杭电暑期多校9部分题解

文章讨论了两个编程问题:利用记忆化搜索求解将1变为n所需的最少操作次数,以及计算n人分发硬币时期望操作次数。涉及DFS算法、独立事件分析和优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1002 - Shortest path

题目大意

对于一个数 x x x,可以进行以下三种操作:

1.将 x x x 变成 2 ∗ x 2*x 2x

2.将 x x x 变成 3 ∗ x 3*x 3x

3.将 x x x 变成 x + 1 x+1 x+1

给定一个数 n n n,问最少操作几次才能将 1 1 1 变成 n n n

解题思路

最开始想法是建图跑最短路,然后发现空间显然不够,换思路

可以倒过来考虑,最优操作必然是找不大于本身的最大的 2 2 2 3 3 3 的倍数除以 2 2 2 3 3 3

很容易可以想到暴力搜索,但是会超时,考虑记忆化优化就可以了

code

#include <bits/stdc++.h>
using namespace std;
int t, ans;
long long n;
unordered_map <long long, int> v;
int dfs(long long x) {
    if (v.find(x) != v.end()) return v[x];
    return v[x] = min(dfs(x / 2) + x % 2, dfs(x / 3) + x % 3) + 1;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> t;
    v[1] = 0;
    v[2] = v[3] = 1;
    while (t --) {
        cin >> n;
        cout << dfs(n) << "\n";
    }
    return 0;
}

1008 - Coins

题目大意

n n n 个人,每个人有 a i a_i ai 个硬币,每次操作可以选择任意 A ,   B A,\space B A, B 两个人,将 A A A 1 1 1 枚硬币给 B B B,如果这次操作后 A A A 没有硬币,则 A A A 退出游戏,问最后将所有硬币集中到一个人手上的期望操作次数

解题思路

先试试模拟,只有两个人的时候答案是 a 1 ∗ a 2 a_1*a_2 a1a2,再推三个人,四个人,发现结果刚好是 ∑ i = 1 n ∑ j = i + 1 n a i ∗ a j \sum_{i=1}^n\sum_{j=i+1}^na_i*a_j i=1nj=i+1naiaj

听说题解讲了鞅的停时定理,咱也不会,但是其实不难发现每两个人之间的游戏其实是独立事件,也可以推出结论

注意卡亿下时间就好了

code

#include <bits/stdc++.h>
using namespace std;
int t, n, a;
__int128 ans, sum;
inline void write(__int128 x) {
    if (x > 9) write(x / 10);
    cout << (char)(x % 10 + '0');
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> t;
    while (t --) {
        cin >> n; sum = ans = 0;
        for (int i = 1; i <= n; ++ i)
            cin >> a, ans += sum * a, sum += a;
        write(ans); cout << "\n";
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值