Codeforces 1629 F2. Game on Sum (Hard Version) —— 杨辉三角,暴力,找规律

本文介绍了一道关于动态规划和博弈论的题目,玩家初始持有数字0,可以从中选择0到k之间的任意实数,对手可以选择加或减这个数字。目标是经过n轮操作后,使对手至少m轮加上你选择的数字,求最大可能的数字。通过观察数据和画图,得出解决方案与n-m-1的关系,最终使用动态规划求解。

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

This way

题意:

你手上有一个数字,一开始是0,每次可以选择[0,k]中任意一个实数。然后由对手决定加还是减去这个数字。总共n轮,并且对手至少要有m轮加上你手中的数字。你希望数字尽可能大,对手希望数字尽可能小。如果你们双方都做出最优抉择,问数字最大是多少。

题解:

有了上题的基础就比较好做了。
观察数据往往能给出思路,看到是1e6,就说明有暴力可能,否则不就给出1e9了吗。
画一下图:

在这里插入图片描述
假设下面红点是要求的值,我们将它所对应的关系画出来:

在这里插入图片描述
看到这个右上斜的这里,1,3,6,10是否有点眼熟呢。
我们可以看到位于(7,4)。
再多画一些图就可以看到是跟n-m-1有关。列一下就可以发现是这样一个公式:

for(ll i=m,j=n-m-1;i>=1;i--,j++)
    ans=(ans+i*fac2[i-1]%mod*c(j,n-m-1))%mod;
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
#define ll long long
const ll mod=1e9+7;
ll qpow(ll a,ll b){ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;}
ll fac[N],inv[N],fac2[N],inv2[N];
ll c(ll n,ll m){
    if(m<0||m>n)return 0;
    if(n==m||m==0)return 1;
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
    fac[1]=1;
    for(int i=2;i<N;i++)fac[i]=fac[i-1]*i%mod;
    inv[N-1]=qpow(fac[N-1],mod-2);
    for(int i=N-2;i;i--)
        inv[i]=inv[i+1]*(i+1)%mod;
    inv2[0]=1,fac2[0]=1;
    for(ll i=1;i<N;i++)fac2[i]=fac2[i-1]*2%mod,inv2[i]=qpow(fac2[i],mod-2);
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        if(n==m){
            printf("%lld\n",1ll*n*k%mod);
            continue;
        }
        ll ans=0;
        for(ll i=m,j=n-m-1;i>=1;i--,j++)
            ans=(ans+i*fac2[i-1]%mod*c(j,n-m-1))%mod;
        printf("%lld\n",ans*k%mod*inv2[n-1]%mod);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值