hdu 4489 The King’s Ups and Downs(动态规划)

题目大意:

        有n个士兵,身高分别为1--n,问这n个士兵排成一种每个士兵比旁边的两个人都高或都矮的队列的种数。

解题思路:

        动态规划问题。f[i][0]代表i个人的队列,这个队列的第一个人比第二个人矮的排列个数,f[i][1]代表i个人的队列,这个队列的最后一个人比倒数第二个人矮的排列个数。由对称性得f[i][0] == f[i][1],记i个人的排列个数为ans,则ans = (f[j][1]*f[i-j-1][0]*c(i-1,j)), 0 <= j < i。f[i][0] = ans/2,f[i][1] = ans/2。因为可以假设每次新加入的人的身高是最高的,第i个人可以放在0到i-1的任意位置。所以i的前面后后面分别有j个人和i-j-1个人,且前j个人的最后一个要比倒数第二个人矮,后i-j-1个人的第一个人要比第二个人要矮。前j个人可以在i-1个人中任选。

代码:

#include 

using namespace std;

long long c[25][25];
long long f[25][2];

int main()
{
    int d,n,p;
    for(int i = 1; i < 20; i ++){
        c[i][0] = 1;
        c[i][i] = 1;
        for(int j = 1; j < i; j ++){
            c[i][j] = c[i-1][j] + c[i-1][j-1];
        }
    }
    f[0][0] = 1;
    f[0][1] = 1;
    f[1][0] = 1;
    f[1][1] = 1;
    for(int i = 2; i <= 20; i ++){
        long long ans = 0;
        for(int j = 0; j < i; j ++){
            ans += f[j][1] * f[i-j-1][0] * c[i-1][j];
        }
        f[i][0] = ans/2;
        f[i][1] = ans/2;
    }
    cin >> p;
    for(int i = 0; i < p; i ++){
        cin >> d >> n;
        cout << d << " ";
        if(n == 1) cout << 1 << endl;
        else cout << 2*f[n][0] << endl;
    }
    return 0;
}


你可能感兴趣的:(hdu,动态规划)