HDU 4489 The King's Ups and Downs

Posted gaawing.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4489 The King's Ups and Downs相关的知识,希望对你有一定的参考价值。

题目链接

问的是n个不一样的数,大小交替,或者小大交替的种类数量。

n个数,想象成[1,n]的自然数即可。

我们假设大小交替得到的长度为i的排列数为dp1[i],小大交替得到的长度为i的排列数为dp2[i],因为是对称的,其实应该有dp1=dp2,我们要计算的总和sum=dp1+dp2。

我们从小到大考虑各个数,一个个插入队列,考虑到第i个数,称为ai,ai比前i-1个数都大,可以插入的位置j∈[1,i]。

ai插入的位置为j时,前面的i-1个人比自己小,选择出来排列的情况有C(i-1,j-1)。插入第j个位置,ai属于“高”,要求ai前面和ai衔接的情况是低高,ai和后面一个衔接的情况是低高。所以插入j位置时候的排列数有 dp1[j-1] * dp2[i - j] * c[i-1][j-1]种。

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mst(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(ll i=(a);i<(b);++i)
const int inf = 0x3f3f3f3f, maxN = 25 + 5;
int N, M, T;

ll dp1[maxN];
ll dp2[maxN];
ll sum[maxN];
ll c[maxN][maxN];

ll cal(int n, int m) {
    c[1][0] = c[1][1] = 1;
    rep(i, 2, n) {
        c[i][0] = 1;
        rep(j, 1, n)
            c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    cal(20, 20);
    dp1[0] = dp1[1] = dp2[0] = dp2[1] = 1;
    sum[1] = 1;
    rep(i, 2, 20 + 1) {
        sum[i] = 0;
        rep(j, 1, i + 1)
            sum[i] += (dp1[j - 1] * dp2[i - j] * c[i - 1][j - 1]);
        dp1[i] = dp2[i] = sum[i] / 2;
    }
    scanf("%d", &T);
    rep(i, 1, T + 1) {
        scanf("%d%d", &M, &N);
        printf("%d %lld\n", M, sum[N]);
    }
    return 0;
}

 

以上是关于HDU 4489 The King's Ups and Downs的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4489 The King’s Ups and Downs

HDU 4489 The King’s Ups and Downs(DP + 组合数)

HDU 3861 The King's Problem(强连通分量缩点+最小路径覆盖)

HDU3861-The King’s Problem(有向图强连通缩点+最小路径覆盖)

HDU——T The King’s Problem

HDU3861The King’s Problem