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\n",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

猜你喜欢

转载自www.cnblogs.com/shandongs1/p/9915405.html
今日推荐