• Acwing-271-杨老师的照相排列(DP)


    链接:

    https://www.acwing.com/problem/content/273/

    题意:

    杨老师希望给他的班级拍一张合照。

    学生们将站成左端对齐的多排,靠后的排站的人数不能少于靠前的排。

    例如,12名学生(从后向前)可以排列成每排5,3,3,1人,如下所示:

    X X X X X
    X X X
    X X X
    X
    同时,杨老师希望同行学生身高从左到右依次降低,同列学生身高从后向前依次降低。

    还以12名学生为例,给学生们编号(号码越小代表身高越高)后,按照此规则可进行如下两种安排:

    1 2 3 4 5 1 5 8 11 12
    6 7 8 2 6 9
    9 10 11 3 7 10
    12 4
    杨老师希望知道给定每排的人数,在满足规则的情况下,一共能有多少种位置安排。

    例如,规定一共三排,每排3,2,1人,则共有16种安排方法如下:

    123 123 124 124 125 125 126 126 134 134 135 135 136 136 145 146
    45 46 35 36 34 36 34 35 25 26 24 26 24 25 26 25
    6 5 6 5 6 4 5 4 6 5 6 4 5 4 3 3
    现在请你编写一个程序,确定在给定每排人数的情况下,不同安排的数量。

    思路:

    建立DP[i][j][k][l][m],表示每一行站了i,j,k,l,m个人时的排列种数.
    可以有第一行开始往后推,当某行人数少一个时依然大于等于前一行就可以将少一个人的状态转移过来.
    注意输入是从后往前输入的

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    LL Dp[35][35][35][35][35];
    int a[10];
    int k;
    
    int main()
    {
        while (~scanf("%d", &k) && k)
        {
            memset(a, 0, sizeof(a));
            memset(Dp, 0, sizeof(Dp));
            for (int i = k;i >= 1;--i)
                scanf("%d", &a[i]);
            Dp[0][0][0][0][0] = 1;
            for (int i = 0;i <= a[1];i++)
            {
                for (int j = 0;j <= a[2];j++)
                    for (int x = 0;x <= a[3];x++)
                        for (int y = 0;y <= a[4];y++)
                            for (int z = 0;z <= a[5];z++)
                            {
                                if (i-1 >= 0)
                                    Dp[i][j][x][y][z] += Dp[i-1][j][x][y][z];
                                if (j-1 >= 0 && j-1 >= i)
                                    Dp[i][j][x][y][z] += Dp[i][j-1][x][y][z];
                                if (x-1 >= 0 && x-1 >= j)
                                    Dp[i][j][x][y][z] += Dp[i][j][x-1][y][z];
                                if (y-1 >= 0 && y-1 >= x)
                                    Dp[i][j][x][y][z] += Dp[i][j][x][y-1][z];
                                if (z-1 >= 0 && z-1 >= y)
                                    Dp[i][j][x][y][z] += Dp[i][j][x][y][z-1];
    //                            cout << Dp[i][j][x][y][z] << endl;
                            }
            }
            printf("%lld
    ", Dp[a[1]][a[2]][a[3]][a[4]][a[5]]);
        }
    
        return 0;
    }
    
  • 相关阅读:
    maven 仓库配置 pom中repositories属性
    CentOS下SVN服务的启动与关闭
    python爬虫登录
    git pull“No remote repository specified”解决方法
    更新到mysql 5.7后解决0000-00-00日期问题
    maven仓库中有jar包pom还报错
    navicat链接mysql 8 出现 2015 authentication plugin 'caching_sha2_password' 错误
    Confluence JIRA快速入门
    SilverLight:基础控件使用(2)-ComboBox,ListBox控件
    SilverLight:基础控件使用(1)
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11469266.html
Copyright © 2020-2023  润新知