zoukankan      html  css  js  c++  java
  • POJ-2279 杨老师的照相序列 玄学多维DP

    问题描述

    有 N 个学生合影,站成左端对齐的 k 排,每排分别有 N1,N2,…,Nk 个人。 (N1≥N2≥…≥Nk),第1排站在最后边,第 k排站在最前边。
    学生的身高互不相同,把他们从高到底依次标记为 1,2,…,N。
    在合影时要求每一排从左到右身高递减,每一列从后到前身高也递减。
    问一共有多少种安排合影位置的方案?
    下面的一排三角矩阵给出了当 N=6,k=3,N1=3,N2=2,N3=1时的全部16种合影方案。注意身高最高的是1,最低的是6。

    输入格式

    输入包含多组测试数据。
    每组数据两行,第一行包含一个整数k表示总排数。
    第二行包含k个整数,表示从后向前每排的具体人数。
    当输入k=0的数据时,表示输入终止,且该数据无需处理。

    输出格式

    每组测试数据输出一个答案,表示不同安排的数量。
    每个答案占一行。

    数据范围

    1≤k≤5,学生总人数不超过30人。

    分析

    首先说一下题意,这题说的很绕,其实简化版就是保证每一列单调递减,每一行单调递减,求方案数,肯定是dp啦
    这个DP其实也挺玄学的,和那个生日party挺像,我们首先来确定一下dp数组的定义,它表示的肯定是合理的方案数,关键是开几维,每一维表示什么,最初的考虑,开两维,一维表示排数,另一维表示每排最多学生数,这样好像确定不了状态,所以肯定不行。那我们怎么确定状态呢,要使它能够表示出来,并且还能进行转移,而且表示的状态确定,那么什么样才能确定?

    手动画图发现这几个矩形的轮廓就能确定出一个状态,转移怎么办?考虑对最后一个人分类讨论,它是排在第一行还是第二行还是第几行,因为它是最后一个人,所以多他少他都一样,于是就加上没有他的方案数,就完成了转移。因为只有五行,所以开五维就行,别小看这五维,因为有多组数据涉及到(memset),所以数组不能开的太大,每维开35都会T掉,因为355就是(52,521,875),对这个(memset)肯定T,开32左右就行了。

    不要忘了longlong哦

    #include<iostream>
    #include<cstring>
    #define g dp[i][j][c][d][e]
    using namespace std;
    const int N=31;
    long long dp[N][N][N][N][N];
    int a[6];
    int main(){
        int k;
        while(cin>>k&&k){
            memset(a,0,sizeof(a));
            memset(dp,0,sizeof(dp));
            dp[0][0][0][0][0]=1;
            for(int i=1;i<=k;i++)
                cin>>a[i];
            for(int i=0;i<=a[1];i++)
            for(int j=0;j<=min(i,a[2]);j++)
            for(int c=0;c<=min(j,a[3]);c++)
            for(int d=0;d<=min(c,a[4]);d++)
            for(int e=0;e<=min(d,a[5]);e++){
                if(i&&i-1>=j)g+=dp[i-1][j][c][d][e];
                if(j&&j-1>=c)g+=dp[i][j-1][c][d][e];
                if(c&&c-1>=d)g+=dp[i][j][c-1][d][e];
                if(d&&d-1>=e)g+=dp[i][j][c][d-1][e];
                if(e)g+=dp[i][j][c][d][e-1];
                
            }
            cout<<dp[a[1]][a[2]][a[3]][a[4]][a[5]]<<endl;
        }
    }
    
  • 相关阅读:
    地狱少女....
    火影忍者&nbsp;是时候结束了
    1942
    待查
    什么是傻瓜
    公车艳遇
    初一
    继承
    第四周学习笔记
    查找里程————mooc《面向对象程序设计——Java语言》-(浙大翁凯)第三周编程题
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12634707.html
Copyright © 2011-2022 走看看