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 <iostream>

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值