【Codeforces 1453D】Checkpoints

题目链接

链接

翻译

每个阶段都有 (frac{1}{2}) 的几率失败,失败了会回到上一个存档点。

想让玩家的期望尝试次数为 (k),问你能否设计出一个不超过 (2000) 级台阶的策略,满足这个要求。

题解

如果只有一个 (1) 的话,那么期望尝试次数为 (2)。假设后面出现了一个 (0),即 10,那么到达第 (2) 层且通过了第二层(能够到达第三层了)的期望次数

是多少呢? 第一层通过了,次数是 (2),然后到达第二层,进行一次尝试。也即 (2+1=3)。但是第二层也只有 (frac{1}{2}) 的几率成功。

所以也应该要乘 (2),即到达第二层且通过第二层的期望次数为 (2*(2+1)=6)。(失败了就要重新从第一层再上)

不难看出,假设 100000... 的长度为 (i),设 (x_i) 表示 (i) 层都通过的期望次数。则 (x_{i+1}=2*(x_i+1)) 也即 (x_i = 2^{i+1}-2)

并且,只要再出现一个 (1) 了,就要重新算期望,即 (1) 把不同的段分隔开了。

然后说下构造策略,首先,(x_i) 总是一个偶数,所以 (k) 为奇数直接 (-1)

然后,对于所给的偶数期望 (k),我们可以这么玩。会发现 11000.. (注意这里开头有两个连续 (1),长度设为 (i+1)) 对应的需要重新试的次数为 (2^{i+1}),因为加上了第一个 (1) 的两次。

只不过这里 (i>=1),所以,对于 (kge4) 的时候,我们只要用 (11000..) 这样对应的 (2^{(i+1)}) 去减 (k) 就好。

因为二进制分解的缘故,我们总能让 (k) 对应的二进制中大于等于 (2^2) 对应的位都变成 (0),因此一直减的结果就是 (k) 最后等于 (2) 或者 (0)

等于 (2) 的时候再补一个 (1) 就好啦。

构造出来的层数是 (1+2+3...log_2K) 这个数量,不会超过 (2000)

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;

vector<int> ans;

int main(){
    // freopen("C://1.cppSourceProgram//rush.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0);
    int T;
    cin >> T;

    while (T--){
        LL k;
        cin >> k;
        //[1] 特殊判断
        if (k % 2 == 1){
            cout << -1 << endl;
            continue;
        }
        //[2] 用1(期望值为2, 10000...0(1000..0长度为 i 期望值为2^(i+1)-2
        //合在一起就是 2^(i+1), 但是这里 i >= 1
        //所以如果k >= 4, 那么就用11000的 batch 减
        ans.clear();
        while (k >= 4){
            ans.push_back(1);
            ans.push_back(1);
            LL cur = 4;
            int i = 1;
            while (cur*2 <= k){
                cur*=2;
                i++;
            }
            for (int j = 1;j <= i-1; j++){
                ans.push_back(0);
            }
            k -= cur;
        }
        //k=2或k=0
        if (k == 2){
            ans.push_back(1);
        }
        cout << (int)ans.size() << endl;
        int len = ans.size();
        for (int i = 0;i < len; i++){
            cout << ans[i];
            if (i == len-1){
                cout << endl;
            }else{
                cout << " ";
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/AWCXV/p/14148214.html