Describe
给你男孩数目n(1<=n<=150),女孩数目m(1<=m<=150)。现在要你求有几种安排的方法使得任意一段差值最多为k(1<=k<=20)。
Sample Input
1 2 1
Sample Output
1
这一题一看就是DP
设dp[i][j][x1][x2]
表示当前状态i个男孩j个女孩
男孩最多比女孩多x1个
女孩最多比男孩多x2个
时的方案种数。
那么推出DP方程:
dp[i+1][j][x1+1][max(x2-1,0)]+=dp[i][j][x1][x2]) (max是防止负数的情况)
#include<cstdio>
#include<cstring>
using namespace std;
int f[160][160][30][30];
int _max(int x,int y){return x>y?x:y;}
int main()
{
int n,m,k;scanf("%d%d%d",&n,&m,&k);
f[0][0][0][0]=1;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
for(int x=0;x<=k;x++)
{
for(int y=0;y<=k;y++)
{
if(x+1<=k&&i+1<=n)
{
f[i+1][j][x+1][_max(0,y-1)]+=f[i][j][x][y];
f[i+1][j][x+1][_max(0,y-1)]%=12345678;
}
if(y+1<=k&&j+1<=m)
{
f[i][j+1][_max(0,x-1)][y+1]+=f[i][j][x][y];
f[i][j+1][_max(0,x-1)][y+1]%=12345678;
}
}
}
}
}
int ans=0;
for(int x=0;x<=k;x++)
{
for(int y=0;y<=k;y++)
{
ans+=f[n][m][x][y];
ans%=12345678;
}
}
printf("%d\n",ans);
return 0;
}