uva 10128 Queue

数学递推(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;
}
原文地址:https://www.cnblogs.com/scau20110726/p/2880268.html