题解:CF1628D1 Game on Sum (Easy Version)
CF1628D1 题解
题面
题意
初始时,有一个数 ans=0。
有两个人,第一个人要在 [0,k] 选出一个实数 t。
第二个人可以选择让 ans 加 t 或减 t。
总共有 n 轮,第二个人至少要操作 m 次,且两个人都会使用最优策略。
思路
容易发现,k 在题目中没啥大用,于是我们就假设 k=1,这时候设最后的 ans 就为 dp[n][m]。
开始考虑 dp 的转移方程,可以容易得到。
dp[i][j]=maxt=0/1{min(dp[i−1]j−1]+t,dp[i−1][j]−t)}。
里面的是第二个人是否选择操作,外面的是第一个人要的最优的操作。
于是,由于 t 只可能为 0 或 1,所以就可以进行分类讨论。
- 若 dp[i−1][j]−dp[i−1][j−1]⩽2,则 dp[i][j]=dp[i−1][j−1]+dp[i−1][j]2。
- 若 dp[i−1][j]−dp[i−1][j−1]>2,则 dp[i][j]=dp[i−1][j−1]+1。
接下来我们发现对于一个 dp[n][m],有 dp[n][m+1]−dp[n][m]⩽2,证明如下。
证明:dp[n][m+1]−dp[n][m]=dp[n−1][m]+d[n−1][m+1]2−dp[n−1][m−1]+dp[n−1][m]2=dp[n−1][m+1]−dp[n−1][m−1]2=dp[n−1][m+1]−dp[n−1][m]2+dp[n−1][m]−dp[n−1][m−1]2⩽22+22=2
即 dp[n][m+1]−dp[n][m]⩽2。
所以,dp[i][j] 只能为 dp[i−1][j−1]+dp[i−1][j]2。
观察到,除去分数线,就是一个杨辉三角,但是,显然,这样会 TLE(困难版),所以考虑线性统计 ans。
可以考虑 dp[i][i] 对 dp[n][m] 的影响,除去分数线,会发现其实就是从 (i,i) 开始只能向下或向右下前进到 (n,m) 的方案数,但是由于 dp[i+1][i+1] 是边界值,所以必能经过 (i+1,i+1),那么就相当于从 (i,i+1) 出发到 (n,m) 的方案数,于是,就为 Cm−in−i−1。
当然,这里就有人问了,为什么呢?
首先,这是一个杨辉三角形(除去分数线)没错吧?于是通过数学归纳法可以证明杨辉三角形第 n 行的第 m 个为 Cmn(m⩾2)。
证明:已知,杨辉三角的第一行为 1,第二行为 1,1,两行均满足猜想。
接下来,对于第 n 行(n>2),第 m 个数(m⩾2)为 Cm−1n−1+Cmn−1=(n−1)×(n−2)×⋯×(n−m+1)(m−1)!+(n−1)×(n−2)×⋯×(n−m)m!=(n−1)×(n−2)×⋯×(n−r+r)m!=(n−1)×(n−2)×⋯×(n−m)m!=Cmn
证毕。
接下来,再加上分数线,就可以得到 dp[n][m]=m∑i=1i×Cm−in−i−12n−i。
于是就有 ans=k×m∑i=1i×Cm−in−i−12n−i。
预处理即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int INV=5e8+4,mod=1e9+7,MN=1e6+1;
//INV是2在模mod意义下的乘法逆元,在此意义下*INV就等价于/2
long long fac[MN],inv[MN],T,n,m,k,ans;
//fac[i]表示i!的值,inv[i]表示fac[i]在模1e9+7意义下的乘法逆元
long long ksm(long long a, long long b) {
long long res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b=b>>1;
}
return res;
}
long long C(long long m, long long n) {
if(n==m||n==0) return 1;
return fac[m]*inv[n]%mod*inv[m-n]%mod;
}
int main(){
fac[0]=1;
for(long long i=1; i<MN; i++){
fac[i]=fac[i-1]*i%mod;
inv[i]=ksm(fac[i],mod-2);
}
scanf("%lld %lld %lld",&n,&m,&k);
if(n==m) printf("%lld\n",n*k%mod);
else{
for(long long i=1; i<=m; i++) ans=(ans+ksm(INV,n-i)*i%mod*C(n-i-1,m-i)%mod)%mod;
printf("%lld\n",ans*k%mod);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!