数学递推(DP)
题意:有n个人,身高各不相同排成一列。从前面 看过去能看到p个人,后后面看过去能看到r个人。矮的人会被高的人挡着看不到。问满足p,r的情况下,有多少种排列的可能。
/* DP dp[i][j][k]表示队列中有i个人,从前面可以看到j个人,后面可以看到k个人有多少种可能 策略:从空队列开始,往其中插入人,从最高到最低插入,每次插入有3种位置,一种在队首,则从前面看的人数会加1, 一种在队尾,则从队尾看的人数会加1,一种在中间(已经有n人在队中,那么有n-1个插入位置),则从队首和队尾看的人数 都不会增加 状态转移方程 dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j][k-1]+(i-2)*dp[i-1][j][k] */ #include <cstdio> #include <cstring> #define N 15 long long dp[N][N][N]; int n,p,r; void DP() { memset(dp,0,sizeof(dp)); dp[1][1][1]=1; for(int i=2; i<=13; i++) for(int j=1; j<=i; j++) for(int k=1; k<=i; k++) dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j][k-1]+(i-2)*dp[i-1][j][k]; return ; } int main() { int Case; DP(); scanf("%d",&Case); while(Case--) { scanf("%d%d%d",&n,&p,&r); printf("%lld\n",dp[n][p][r]); } return 0; }