题目来源:POJ:http://poj.org/problem?id=2279 SPOJ:https://www.spoj.com/problems/GNYR04H/

题意翻译

题目描述

杨先生希望为他的班级拍照。学生将排成一行,每行不超过后面的行,并且行的左端对齐。例如,可以安排12名学生排列(从后到前)5,3,3和1名学生。

X X X X X
X X X
X X X
X

此外,杨先生希望每排学生安排高度从左到右减少。此外,学生身高应从后向前减少。想想看,杨先生看到,对于这个12人的例子,至少有两种安排学生的方式(数字代表高度,其中1代表最高):

 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

杨先生认为,手动点数对于任何合理数量的学生来说都不会很有效。他通过编写计算机程序来帮助你确定一组给定行的学生的不同安排数量。


输入

输入描述了一系列测试,每个测试分两行描述。第一行将行数k作为十进制整数。第二行包含从后到前的行的长度(n {1} 1 ,n {2} 2 ,...,n _ {K} ķ )作为由单个空格分隔的十进制整数。问题集以行计数为0的行结束。最多不会超过5行,学生总数N(行长度总和)最多不超过30行。


输出

对于每个测试用例输出一个整数:N个学生排列在给定行中的数量,以便高度从左到右沿着每行减少,并且从后到前沿着每列减小(假定所有高度都不同)。结果应该分开。输入数据将被选择,以便结果总是适合一个无符号的32位整数。


样例输入

1

30

5

1 1 1 1 1

3

3 2 1

4

5 3 3 1

5

6 5 4 3 2

2

15 15

0


样例输出

1

1

16

4158

141892608

9694845

解析:

这题说实话思路很难想到。主要是一个单调性的维护。


看到这题应该第一个反应应该是用每一行的人数作为dp的状态,从每行都没有人的情况出发,然后每次做在某一行添加一人的决策,求解可能情况数量。

既便这一点很容易想到,但是还有一个棘手的问题——单调性如何解决,即每行每列的学生身高是递减的。

实际上我们并不用管某个位置上的学生身高具体是多高,只要直到整体具有单调性就可以了。

我们需要做一些约束,以使得全局具有单调性。首先,在这道题里,局部单调性可以导出全局单调性(关键所在),记住它

而且题目告诉我们,每行不超过后面的行。

我们得出这样一个结论:如果我们按照从高到低的次序添加学生,根据单调性,每次增加一个学生,这个增加的学生的高度必然小于上一个增加的学生,而根据题意,我们必须把这个新的学生安排到之前放的学生的右边的列或者是之前放的学生的前面的行

于是在每一次状态转移中,我们只需要动态维护某一行的人数比它前面那一行的人数要多就行了。

注意:对于每行放置的每一个学生,每轮循环都从0开始,否则无法覆盖问题空间。


话说为什么有人说要动态开数组,我没开不也过了???

参考代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 31
#define MOD 2520
#define E 1e-12
#define ri register int
using namespace std;
unsigned int dp[N][N][N][N][N],a[N];
int main()
{
int k;
while(cin>>k&&k!=)
{
int cnt=;
memset(a,,sizeof(a));
memset(dp,,sizeof(dp));
for(ri i=;i<=k;i++) scanf("%d",&a[i]);
dp[][][][][]=;
for(ri a1=;a1<=a[];a1++)
for(ri a2=;a2<=a[];a2++)
for(ri a3=;a3<=a[];a3++)
for(ri a4=;a4<=a[];a4++)
for(ri a5=;a5<=a[];a5++){
if(a1<a[]) dp[a1+][a2][a3][a4][a5]+=dp[a1][a2][a3][a4][a5];
if(a2<a[]&&a1>a2) dp[a1][a2+][a3][a4][a5]+=dp[a1][a2][a3][a4][a5];
if(a3<a[]&&a2>a3) dp[a1][a2][a3+][a4][a5]+=dp[a1][a2][a3][a4][a5];
if(a4<a[]&&a3>a4) dp[a1][a2][a3][a4+][a5]+=dp[a1][a2][a3][a4][a5];
if(a5<a[]&&a4>a5) dp[a1][a2][a3][a4][a5+]+=dp[a1][a2][a3][a4][a5];
}
cout<<dp[a[]][a[]][a[]][a[]][a[]]<<endl;
}
return ;
}

SP15637 GNYR04H - Mr Youngs Picture Permutations[DP]的更多相关文章

  1. $SP15637\ GNYR04H\ -\ Mr\ Youngs\ Picture\ Permutations$

    传送门 Description 杨先生希望为他的班级拍照.学生将排成一行,每行不超过后面的行,并且行的左端对齐.例如,可以安排12名学生排列(从后到前)5,3,3和1名学生. X X X X X X ...

  2. SP15637 Mr Youngs Picture Permutations 高维动态规划

    问题描述 LG-SP 题解 发现\(n,k\)都非常小,尤其是\(k,k\le 5\),于是直接开\(5\)维进行\(\mathrm{DP}\) 用记忆化搜索实现. \(\mathrm{Code}\) ...

  3. 【题解】POJ2279 Mr.Young′s Picture Permutations dp

    [题解]POJ2279 Mr.Young′s Picture Permutations dp 钦定从小往大放,然后直接dp. \(dp(t1,t2,t3,t4,t5)\)代表每一行多少人,判断边界就能 ...

  4. 轮廓线DP:poj 2279 Mr. Young's Picture Permutations

    poj 2279 Mr. Young's Picture Permutations \(solution:\) 首先摘取一些关键词:(每行不超过它后面的行)(每排学生安排高度从左到右减少)(学生的高度 ...

  5. POJ2279 Mr Young's Picture Permutations

    POJ2279 Mr Young's Picture Permutations 描述: 有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前.学生身高依次是1… ...

  6. Mr. Young's Picture Permutations

    Mr. Young's Picture Permutations 给出一个有k列的网格图,以及每列图形的高度\(n_i\),下端对齐,保证高度递减,设有n个网格,询问向其中填1~n保证每行每列单调递增 ...

  7. bzoj 2483: Pku2279 Mr. Young's Picture Permutations -- 钩子公式

    2483: Pku2279 Mr. Young's Picture Permutations Time Limit: 1 Sec  Memory Limit: 128 MB Description   ...

  8. poj2279 Mr. Young's Picture Permutations[勾长公式 or 线性DP]

    若干人左对齐站成最多5行,给定每行站多少个,列数从第一排开始往后递减.要求身高从每排从左到右递增(我将题意篡改了便于理解233),每列从前向后递增.每个人身高为1...n(n<=30)中的一个数 ...

  9. poj2279——Mr. Young's Picture Permutations

    Description Mr. Young wishes to take a picture of his class. The students will stand in rows with ea ...

随机推荐

  1. 三节课MINI计划第二周

    任务:完成一份用户反馈的收集,并进行分析 第一步:去你能想到的公开.非公开渠道收集最近90天,至少40条和B站相关的有效用户差评反馈,并根据你对业务的理解分类整理,以表格的形式进行整理,以图片的方式提 ...

  2. 20190722java学习习惯小结

    1.周一——周六: 学习: 周日: 巩固练习测试. 2.java 大数据. python 人工智能 .. 3.写技术博客! 4.python应用: 人工智能.web开发.自动化运维.数据分析.爬虫.游 ...

  3. C#实现动态发布IIS站点帮助类

    准备工作: 1.引用 System.DirectoryServices 系统程序集 2.引用 Microsoft.Web.Administration 程序集,类库位置在 C:\Windows\Sys ...

  4. React中的setState到底发生了什么?

    https://yq.aliyun.com/ziliao/301671 https://segmentfault.com/a/1190000014498196 https://blog.csdn.ne ...

  5. Spring Boot代码生成

    一.背景 在Java web开发中,虽然Spring boot已经帮助我们简化了很多工作,但项目中庞杂的业务仍然需要自己去编写较多的 entity,vo,Mapper,Service, Control ...

  6. mysql常用操作及常见问题

    常用操作 mysql备份: --整库备份 docker exec 容器ID mysqldump -uroot -p密码 --databases 库名 > 库名.sql --仅导出表和数据 mys ...

  7. 【LOJ】#2210. 「HNOI2014」江南乐

    LOJ#2210. 「HNOI2014」江南乐 感觉是要推sg函数 发现\(\lfloor \frac{N}{i}\rfloor\)只有\(O(\sqrt{N})\)种取值 考虑把这些取值都拿出来,能 ...

  8. Java Socket 的工作机制

    转载,请加上原文链接: 目录 socket 对象的创建时间 socket 通信可能会造成死锁 socket 对象的创建时间 这里需要一点TCP的知识, TCP状态分析请看 --> TCP转态转换 ...

  9. 剑指offer58:对称的二叉树。判断一颗二叉树是不是对称的,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的

    1 题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 2 思路和方法 定义一种遍历算法,先遍历右子结点再遍历左子结点:如对称先序 ...

  10. Oracle查询部门工资最高员工的两种方法 1、MAX()函数 2、RANK()函数

      本文以SCOTT用户下初始的EMP表为参考.代码可直接使用.   查询EMP表结构的语句如下,[代码1]: DESC EMP;   EMP表结构如下:[结果1]: SQL> DESC EMP ...