2019杭电多校第七场

1001 A + B = C

考虑最终答案的形式(列竖式),因为两个数相加最多只会进一位,所以C要么和A/B对齐,要么往前多一位,暴力判断四种情况即可

1006 Final Exam

本题的难点在于读题。。
首先题目的直观理解应该是,我给出一种复习方法,那么不管题目怎么分配,我都能做出至少k题,换句话说,我的方案必须可以应付所有的出题情况
那么我们可以反方向考虑,如何构造一种情况让我做不到k道题?也就是说怎么卡掉我的复习方案?
假设每道题的复习时间是 t i t_i ti,一个最暴力的方法就是每道题的分数都是 t i t_i ti
那么如果分数不够用怎么办?注意我们可以让其中 k − 1 k-1 k1道题的分数变少(即我可以让你做出 k − 1 k-1 k1道题),那么显然要让复习分数最多的 k − 1 k-1 k1道题分数变少,当然了肯定是变成0
那么如果剩下的分数小于等于m,那么我们就构造出了一种题目分数方案卡掉我的复习方案,否则我的方案就是一种合法解
从这种方法去想,我们只需要让最少的 n − k + 1 n-k+1 nk+1门课的复习时间总和大于 m m m就好了,平均分配即可

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int T,n,m,k,t;
long long res1,res2;
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        t = m / (n - k + 1) + 1;
        res1 = 1ll * t * (k - 1) + (m + 1);
        cout<<res1<<endl;
    }
    return 0;
}

1010 Just Repeat

如果一种花色的牌只有一个人拥有,那么直接计入答案就好,因为这种花色对策略没有影响
然后考虑两个人都有的花色怎么打
显然不能只考虑自己有多少牌,也要考虑对方有多少牌,因为你出一张牌不但能保证自己能出这个花色,还能封住对面的花色
考虑一个花色,对面有 x x x张,我有 y y y张,那么如果对面出,收益是 − x -x x张(表示能让对面过 x x x张牌),我出收益是 y y y张,所以我出这张牌的收益应该是 x + y x+y x+y
所以我们只需要按照某种花色的总数进行排序,然后轮流取就好
至于做法的正确性证明。。我也不清楚,因为也是猜的结论2333
后来想了一个奇奇怪怪的证明方法:
假设有一种花色的排列顺序,不是按照总数进行排序,并且答案最优
显然必定存在一对相邻的逆序对,不妨设:

花色1花色2
先手 A A A B B B
后手 C C C D D D

如果按照正常的取法应该是先手拿 A A A,后手拿 D D D,先手可以多出 A − D A-D AD张(带符号)
如果我们换一种取法,先手拿 B B B,后手拿 C C C,那么先手可以多出 B − C B-C BC
由于这是最优取法,所以肯定有 A − D &gt; = B − C A-D&gt;=B-C AD>=BC,整理得 A + C &gt; = B + D A+C&gt;=B+D A+C>=B+D
这和题设“逆序对”不符合,故假设不成立
所以当按照总数降序的顺序取最优

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 1000005
using namespace std;
struct node{int x,y;} g[N*2];
int T,n,m,p,i,mod,k,res1,res2,num;
int a[N],b[N],f[N*2],x[N],y[N];
unsigned long long k1, k2;
unsigned long long rng()
{
    unsigned long long k3 = k1, k4 = k2;
    k1 = k4;
    k3 ^= k3 << 23;
    k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
    return k2 + k4;
}
const cmp(const node &a,const node &b) {return a.x+a.y > b.x+b.y;}
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d%d",&n,&m,&p);
        if (p == 1)
        {
            fo(i,1,n) scanf("%d",&a[i]);
            fo(i,1,m) scanf("%d",&b[i]);
        }    else
        {
            scanf("%llu%llu%d",&k1,&k2,&mod);
            fo(i,1,n) a[i] = (int)(rng() % (unsigned long long)mod);
            scanf("%llu%llu%d",&k1,&k2,&mod);
            fo(i,1,m) b[i] = (int)(rng() % (unsigned long long)mod);
        }
        //fo(i,1,n) cout<<a[i]<<" "; cout<<endl;
        //fo(i,1,m) cout<<b[i]<<" "; cout<<endl;
        k = 0;
        fo(i,1,n) f[++k] = a[i];
        fo(i,1,m) f[++k] = b[i];
        sort(f+1,f+n+m+1);
        k = unique(f+1,f+n+m+1) - (f+1);
        fo(i,1,n) a[i] = lower_bound(f+1,f+k+1,a[i]) - f;
        fo(i,1,m) b[i] = lower_bound(f+1,f+k+1,b[i]) - f;
        res1 = res2 = 0;
        fo(i,1,n) x[a[i]]++;
        fo(i,1,m) y[b[i]]++;
        num = 0;
        fo(i,1,k)
        if (x[i] == 0 && y[i] != 0)
        {
            res2 += y[i];
        }    else
        if (x[i] != 0 && y[i] == 0)
        {
            res1 += x[i];
        }    else
        {
            num++; g[num].x = x[i]; g[num].y = y[i];
        }
        sort(g+1,g+num+1,cmp);
        fo(i,1,num)
        {
            if (i % 2 == 1) res1 += g[i].x; else res2 += g[i].y;
        }
        if (res1 > res2) printf("Cuber QQ\n"); else printf("Quber CC\n");
        fo(i,1,n) x[a[i]]--;
        fo(i,1,m) y[b[i]]--;
    }
    return 0;
}

1011 Kejin Player

经典的概率 d p dp dp
f [ i ] f[i] f[i]表示升到 i i i级的期望花费,那么这个期望值应该是满足区间可加性的,即从 i i i级升到 j j j级的期望花费应该是 f [ i ] − f [ j ] f[i]-f[j] f[i]f[j](注意这里不是 j − 1 j-1 j1
分别考虑升级的时候,成功和失败的花费
那么显然有 f [ i + 1 ] = f [ i ] + p i ( a i ) + ( 1 − p i ) ( a i + f [ i + 1 ] − f [ x ] ) f[i+1]=f[i]+p_i(a_i)+(1-p_i)(a_i+f[i+1]-f[x]) f[i+1]=f[i]+pi(ai)+(1pi)(ai+f[i+1]f[x])
成功了就直接升级,失败了就要从 x i x_i xi升级
移项之后 O ( n ) O(n) O(n)预处理即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值