zoukankan      html  css  js  c++  java
  • 58-56: 模拟赛

    带着水印,不想截图

    小迟的比赛
    game.in/.out/.cpp
    【问题描述】
    ⼩迟最近去参加了⼀个锦标赛,这个锦标赛总共有 n 轮⽐赛,最终成
    绩由这 n 轮⽐赛中赢的轮数决定。⾄于⼩迟每⼀轮⽐赛的胜利概率,则取
    决于他在该轮⽐赛之前的战绩。也就是说,如果⼩迟在第 i 轮⽐赛选择积极
    应战,并且前 i-1 轮⽐赛中取得了 j 胜的话,那么第 i 轮⽐赛的胜率概率为
    p[i][j],这⾥我们保证了⼀点就是对于同⼀个 i,p[i][j] 关于 j 的上升保持单
    调不上升(也就是说 p[i][j]<p[i][j+1])。
    ⼩迟观察到这个规则之后,想到了⼀个可能可以使他最终成绩更优的⽅
    法,就是在某些轮⽐赛采取第⼆种策略,故意求败,也就是以 100% 的概率
    输掉该轮⽐赛,从⽽使⾃⼰在后⾯能够遇到更容易对付的对⼿。
    ⼩迟现在已经看到了整个 p 数组,⼩迟希望你能告诉他⼀个最优的策
    略,使得他能最⼤化他的期望赢的轮数。这⾥,定义⼀下期望。假如我们要
    求⼀个事件 A 的期望,那么假如事件 A 以 Pi 的概率结果为 i,那么事件 A
    的期望则是 i*Pi 的和,⼤概的含义就是结果值关于概率的⼀个加权平均数

    输入格式】
    输⼊⽂件名为 game.in。
    输⼊数据第⼀⾏为轮数 n,n 为正整数。
    接下来的 n ⾏,第 i ⾏有 i 个实数,表⽰对应的 p[i][0],....p[i][i-1].
    【输出格式】
    输出⽂件名为 game.out。
    ⼀⾏⼀个实数,表⽰最优策略下期望赢的轮数,保留两位⼩数。
    【样例输入】
    2
    3
    0.5
    0.5 0.5
    【样例输出】
    1.00
    【样例解释】
    由于我们看到对于第 i 轮,⽆论之前战绩如何,胜率都是相同的,因此,
    我们的最优策略应当是每⼀轮努⼒求胜。
    然后,第⼀轮,如果我们赢了,概率为 0.5,输了的概率也为 0.5.
    如果第⼀轮赢了,第⼆轮又赢了,概率为 0.5*0.5=0.25,赢两盘;
    如果第⼀轮赢了,第⼆轮输了,概率为 0.5*(1-0.5)=0.25,赢⼀盘;
    如果第⼀轮输了,第⼆轮赢了,概率为 (1-0.5)*0.5=0.25, 赢⼀盘;
    如果两轮都输了,概率为 (1-0.5)*(1-0.5)=0.25, 赢零盘。
    故期望赢的轮数为 0.25*2+(0.25+0.25)*1+0.25*0=1.
    【数据规模及约定】
    对于 30% 的数据,n≤ 2.
    对于 100% 的数据,1≤n≤1000,0≤p[i][j]≤1.

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=1000+15;
    int n;
    double p[maxn][maxn];
    double f[maxn][maxn];
    int main()
    {
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
         for (int j=0;j<i;j++)
          scanf("%lf",&p[i][j]);
        f[0][0]=1;
        for (int i=0;i<n;i++)
         for (int j=0;j<=i;j++)
          {
              f[i+1][j+1]+=f[i][j]*p[i+1][j];
            f[i+1][j]+=f[i][j]*(1-p[i+1][j]); 
          }
        double ans=0;
        for (int j=0;j<=n;j++) ans+=j*f[n][j];
        printf("%.2lf
    ",ans);
        return 0;
    }

    Yuno like cake
    cake.in/.out/.cpp
    【问题描述】
    双⼗⼀就要来啦!⽽ Yuno 刚刚获得了⼀笔 X 元的奖⾦。那么是不是
    应该清空下购物车呢?
    购物车总共有 N 个物品,每个物品的价格为 V i ,Yuno 想尽可能地把
    ⼿头的奖⾦给花光,所以她要精⼼选择⼀些商品,使得其价格总和最接近但
    又不会超过奖⾦的⾦额。那么 Yuno 最后最少可以剩下多少钱呢?

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define gc getchar()
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    const int N = 45;
    
    #define LL long long
    
    LL a[N];
    LL n, X;
    LL num1[1200000], num2[1200000], tot1, tot2;
    
    bool Cmp(LL aa, LL ba) {
        return aa > ba;
    }
    
    LL b[10000];
    
    int main() {
        n = read(), X = read();
        for(int i = 1; i <= n; i ++) a[i] = read();
        sort(a + 1, a + n + 1);
        int n1 = n / 2, n2 = n - n1;
        int to = (1 << n1) - 1;
        for(int t = 1; t <= to; t ++) {
            LL num = 0;
            for(int i = 0; (1 << i) <= t; i ++) {
                if(t & (1 << i)) num += a[i + 1];
            }
            num1[++ tot1] = num;
        }
        to = (1 << n2) - 1;
        for(int t = 1; t <= to; t ++) {
            LL num = 0;
            for(int i = 0; (1 << i) <= t; i ++) {
                if(t & (1 << i)) num += a[n1 + i + 1];
            }
            num2[++ tot2] = num;
        }
        sort(num1 + 1, num1 + tot1 + 1);
        sort(num2 + 1, num2 + tot2 + 1, Cmp);
        LL Min = 1e18;
        for(int i = 1; i <= tot1; i ++) 
            if(num1[i] == X) {
                cout << 0; return 0;
            } else if(num1[i] < X) {
                Min = min(Min, X - num1[i]);
            }
        for(int i = 1; i <= tot2; i ++)
            if(num2[i] == X) {
                cout << 0; return 0;
            } else if(num2[i] < X) {
                Min = min(Min, X - num2[i]);
            }
        int t1 = tot1;
        int t2 = tot2;
        while(t1 >= 1 && t2 >= 1) {
            while(num1[t1] + num2[t2] > X && t1 >= 1) {
                t1 --;
            }
            if(t1 == 0) break;
            Min = min(Min, X - num1[t1] - num2[t2]);
            t2 --;
        }
        cout << Min;
        
        return 0;
    }

    T3:

    [FJOI2017]矩阵填数

    -------------------------------------------------------------------------------------------------------------------

    这是最近的考试自己想做却又在最后非常无力的一场考试。。。。。。

    主要在T2,由于T1没做出来(vegetable

    所以当时一心想着AT2,生成大数据对拍

    一直没发现排序cmp() 传的int类型

    那这就排不了序了。。。

    查了很长很长时间,最后很慌导致数组开小,gg

    然而,数据太水了,没爆int

  • 相关阅读:
    高斯过程回归
    第一行代码读书笔记3+错误分析
    多项式各种操作
    [BZOJ3625] [Codeforces Round #250]小朋友和二叉树
    [BZOJ2055] 80人环游世世界
    [BZOJ3698] XWW的难题
    [BZOJ3456] 城市规划
    分治FFT
    [BZOJ5306] [HAOI2018]染色
    [BZOJ3380] [USACO2004 Open]Cave Cows 1 洞穴里的牛之一
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9915405.html
Copyright © 2011-2022 走看看