zoukankan      html  css  js  c++  java
  • POJ 2279 Mr. Young's Picture Permutations(dp)

    题目链接

    题目大意

      有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前。学生身高依次是1…N。在合影时候要求每一排从左到右递减,每一列从后面到前也递减,一共有多少总方案。

    解题思路

      考虑放最低的学生的情况,我们会发现,对于所有情况,最低的学生只能放在某一行以及某一列的最后一个位置。假如这个学生不放在行末以及列末,因为他是最低的学生,那么他所在的行和列肯定不会单调。所以说,我们可以根据前面的一个状态来推出后面的一个状态,这个问题可以用dp来求解。
      因为每一排的人数是非递增的。所以对于当前的状态,如果上一行人数和这一行人数不同放在行末肯定也是处于列末的,那么这一行末尾可以放人;如果相同,则只能在最后一行末尾放人。状态转移方程太长了直接看代码吧。。。

    代码1

      因为k最多为5,所以要开一个5维数组,但是直接开满(30^5)会mle。可以考虑一下,如果只在第一排放人,那么第一维最大30;如果在前两排放人,那么第二维最大15;。。。所以只要开一个31161187的数组就够了。

    int n, s[5]; ll dp[31][16][11][8][7];
    int main() {
        while(~scanf("%d",&n) && n) {
            zero(s); zero(dp);
            for (int i = 0; i<n; ++i) scanf("%d", &s[i]);
            dp[0][0][0][0][0] = 1;
            for (int a = 0; a<=s[0]; ++a)
                for (int b = 0; b<=s[1]&&b<=a; ++b) 
                    for (int c = 0; c<=s[2]&&c<=b; ++c)
                        for (int d = 0; d<=s[3]&&d<=c; ++d)
                            for (int e = 0; e<=s[4]&&e<=d; ++e) {
                                ll &t = dp[a][b][c][d][e];
                                if (a>b) t += dp[a-1][b][c][d][e];
                                if (b>c) t += dp[a][b-1][c][d][e];
                                if (c>d) t += dp[a][b][c-1][d][e];
                                if (d>e) t += dp[a][b][c][d-1][e];
                                if (e) t += dp[a][b][c][d][e-1];
                            }
            printf("%lld
    ", dp[s[0]][s[1]][s[2]][s[3]][s[4]]);
        }
        return 0;
    }
    

    代码2

      如果不嫌麻烦。。。也可以动态开内存。。。

    int n, s[5];
    int main() {
        while(~scanf("%d",&n) && n) {
            zero(s);
            for (int i = 0; i<n; ++i) scanf("%d", &s[i]);
            ll *****dp = new ll**** [s[0]+1];
            for (int a = 0; a<s[0]+1; ++a) {
                dp[a] = new ll*** [s[1]+1]; 
                for (int b = 0; b<s[1]+1; ++b) {
                    dp[a][b] = new ll** [s[2]+1];
                    for (int c = 0; c<s[2]+1; ++c) {
                        dp[a][b][c] = new ll* [s[3]+1];
                        for (int d = 0; d<s[3]+1; ++d)
                            dp[a][b][c][d] = new ll [s[4]+1];
                    }
                }
            }
            for (int a = 0; a<=s[0]; ++a)
                for (int b = 0; b<=s[1]; ++b)
                    for (int c = 0; c<=s[2]; ++c)
                        for (int d = 0; d<=s[3]; ++d)
                            for (int e = 0; e<=s[4]; ++e)
                                dp[a][b][c][d][e] = 0;
            dp[0][0][0][0][0] = 1;
            for (int a = 0; a<=s[0]; ++a)
                for (int b = 0; b<=s[1]&&b<=a; ++b) 
                    for (int c = 0; c<=s[2]&&c<=b; ++c)
                        for (int d = 0; d<=s[3]&&d<=c; ++d)
                            for (int e = 0; e<=s[4]&&e<=d; ++e) {
                                ll &t = dp[a][b][c][d][e];
                                if (a>b) t += dp[a-1][b][c][d][e];
                                if (b>c) t += dp[a][b-1][c][d][e];
                                if (c>d) t += dp[a][b][c-1][d][e];
                                if (d>e) t += dp[a][b][c][d-1][e];
                                if (e) t += dp[a][b][c][d][e-1];
                            }
            printf("%lld
    ", dp[s[0]][s[1]][s[2]][s[3]][s[4]]);
            for (int a = 0; a<s[0]+1; ++a) { 
                for (int b = 0; b<s[1]+1; ++b) {
                    for (int c = 0; c<s[2]+1; ++c) {
                        for (int d = 0; d<s[3]+1; ++d) {
                            delete dp[a][b][c][d];
                        }
                        delete dp[a][b][c];
                    }
                    delete dp[a][b];
                }
                delete dp[a];
            }
            delete dp;
        }
        return 0;
    }
    
  • 相关阅读:
    TCP三次握手与四次挥手
    centos7快捷键
    关于学习简单讲解的个人观点
    继承与派生
    python封装
    python之面向对象编程
    python之re模块
    python之hashlib、suprocess模块
    python之shelve、xml、configparser模块
    python之json、pickle模块
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12940243.html
Copyright © 2011-2022 走看看