题目
简化题目,我们用0代表A国士兵,用1代表B国俘虏,题目转化为有多少种长度为(n+m)的合法二进制01串(合法的定义:对于任意的整数k∈[1, n+m],数列的前k个数中,1的个数不少于0)。
————————————————
为了方便理解,我们先思考n=m的情况,我们用向右上方走一步代表1,向右下方走一步代表0,即从(0,0)到坐标(0,2n)有多少种合法走法。
我们用(x,y)表示
从(0,0)到坐标(0,2n)的所有走法为(n,2n)
容易看出合法的走法始终会在x轴的上方(包括x轴)。
不合法的走法必定经过y=-1轴,如下图所示:
我们把第一次经过y=-1轴的点后面的头像翻转,此时所求终点为(-2,2n),易知从(0,0)到(-2,2n)必定经过y=-1轴,必定不合法,求出此时的走法数,用所有的走法数减去不合法的走法数即为合法的走法(即合法01串,即正确的押送俘虏的排列数)。
答案:ans=(n,2n)-(n-1,2n)或(n,2n)-(n+1,2n)
注:(n-1,2n)=(n+1,2n)
这是n=m的情况,类推到一般情况:
ans=(n,n+m)-(n-1,n+m)
下附代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m;
ll f(ll a,ll b) {
ll ans=1;
for(ll i=1;i<=a;i++){
ans*=(b-i+1);
ans%=10007;
}
for(int i=0;i<10005;i++){
for(int j=2;j<=a;j++){
ans*=j;
ans%=10007;
}
}
return ans;
}
int main(){
cin>>n>>m;
ll ans=f(n,n+m)+10007-f(n-1,n+m);
ans%=10007;
cout<<ans;
return 0;
}