题意:
现在有n个1,m个-1,让你构造n+m长度的串,将所有情况的最大前缀和相加。问你答案是多少。
题解:
这道题也就是相当于转换成一个n*m的网格,横轴代表-1,纵轴代表1.那么我们枚举最大前缀的值i,也就是问你有多少路线从(0,0)走到(m,n)的同时正好穿过y=x+i这条线。
那么可以将(0,0)这个点照y=x+i这条线做个对折,到(-i,i)。那么这个点到(n,m)点的路线就都穿过y=x+i这条线。即为
。从(-i,i)到(n,m)的所有路径可以看成有n+m个空,n个放1,m个放-1.
但是要注意需要减去
,也就是减去i+1的答案。枚举的i也必须大于等于n-m。最后一点它的模数是998244853.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244853;
const int N=4e3+5;
ll c[N][N];
int main(){
for(int i=0;i<N;i++)
c[i][0]=c[i][i]=1;
for(int i=1;i<N;i++)
for(int j=1;j<i;j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
int n,m;
scanf("%d%d",&n,&m);
ll ans=0;
for(ll i=n;i&&i>=n-m;i--){
ll sum=(c[n+m][n-i]-(n-i?c[n+m][n-i-1]:0)+mod)%mod;
ans=(ans+sum*i)%mod;
}
printf("%lld\n",ans);
return 0;
}