$SP15637\ GNYR04H\ -\ Mr\ Youngs\ Picture\ Permutations$
Description
杨先生希望为他的班级拍照。学生将排成一行,每行不超过后面的行,并且行的左端对齐。例如,可以安排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
杨先生认为,手动点数对于任何合理数量的学生来说都不会很有效。他通过编写计算机程序来帮助你确定一组给定行的学生的不同安排数量。
Input
输入描述了一系列测试,每个测试分两行描述。第一行将行数k作为十进制整数。第二行包含从后到前的行的长度(n {1} 1 ,n {2} 2 ,...,n _ {K} ķ )作为由单个空格分隔的十进制整数。问题集以行计数为0的行结束。最多不会超过5行,学生总数N(行长度总和)最多不超过30行。
Output
对于每个测试用例输出一个整数:N个学生排列在给定行中的数量,以便高度从左到右沿着每行减少,并且从后到前沿着每列减小(假定所有高度都不同)。结果应该分开。输入数据将被选择,以便结果总是适合一个无符号的32位整数
Solution
大概就是排一个高最大为5的类似倒三角形,然后每一行的数字从左往右递增,每一列的数字从上往下递增,其实就是保证每一个数都大于它左边的数和它上边的数,求满足要求的排列方案数
第一反应就是最多5排啊,这么小就可以直接DP了啊:
$f[a][b][c][d][e]$表示第一排已经站了$a$个人,第二排站了$b$个人.....的方案数
转移:
从小到大的填,一个数可以填在一个位置当且仅当它的左边和上面的数已经填了,或者它就是最左边或最上面的位置,这样就可以保证它大于左边和上面的数了,还要注意每一行的人数不要超过输入给的人数
对了还要注意$MLE$的问题,开空间不能开$f[31][31][31][31][31]$,因为它是一个类似倒三角形(每一行的人数都小于或等于上一行的人数),所以可以推出只要开$f[31][31/2+1][31/3+1][31/4+1][31/5+1]$就可以了
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#define Rg register
#define il inline
#define db double
#define ll unsigned long long
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i--)
using namespace std;
const int N=;
int ct[N],n;
ll f[N][N/+][N/+][N/+][N/+];
int main()
{
while(scanf("%d",&n),n)
{
memset(ct,,sizeof(ct));memset(f,,sizeof(f));
go(i,,n)scanf("%d",&ct[i]);
f[][][][][]=;
go(a,,ct[])
go(b,,ct[])
go(c,,ct[])
go(d,,ct[])
go(e,,ct[])
{
ll t=f[a][b][c][d][e];
if(a<ct[])f[a+][b][c][d][e]+=t;
if(b<ct[]&&a>b)f[a][b+][c][d][e]+=t;
if(c<ct[]&&b>c)f[a][b][c+][d][e]+=t;
if(d<ct[]&&c>d)f[a][b][c][d+][e]+=t;
if(e<ct[]&&d>e)f[a][b][c][d][e+]+=t;
}
printf("%llu\n",f[ct[]][ct[]][ct[]][ct[]][ct[]]);
}
return ;
}
随机推荐
- 云原生生态周报 Vol. 5 | etcd性能知多少
业界要闻 1 Azure Red Hat OpenShift已经GA.在刚刚结束的Red Hat Summit 2019上,Azure Red Hat OpenShift正式宣布GA,这是一个微软和红 ...
- CDQ分治 三维偏序
这应该是一道CDQ分治的入门题目 我们知道,二维度的偏序问题直接通过,树状数组就可以实现了,但是三维如何实现呢? 我记得以前了解过一个小故事,应该就是分治的. 一个皇帝,想给部下分配任务,但是部下太多 ...
- H3C IP 地址格式和表示方法
- Git的提交与查看差异
本文转载于:http://blog.csdn.net/crylearner/article/details/7685158 代码提交 代码提交一般有五个步骤: 1.查看目前代码的修改状态 2.查看代码 ...
- JavaScript 鼠标事件
鼠标事件是Web开发中最常用的一类事件. DOM3级事件中定义了9个鼠标事件,分别如下: click.dbclick.mousedown.mouseenter.mouseleave.mousemove ...
- C# 配置文件存储 各种序列化算法性能比较
本文比较多个方式进行配置文件的存储,对比各个不同算法的读写性能. 在应用软件启动的时候,需要读取配置文件,但是启动的性能很重要,所以需要有一个很快的读取配置文件的方法. 如果你不想看过程,那么请看拖动 ...
- html(四)数据库curd操作与分页查询
数据库操作curd : 1.首先要建立项目处理好自己逻辑包: 其中util工具包中建立两个工具类 jdbc连接和page分页 DBUtil.java: db工具类就是用于连接数据库的jdbc架包,里面 ...
- Vmware虚拟机用户密码忘记了怎么办?
Vmware虚拟机用户密码忘记了怎么办? 虚拟机Linux上用户密码忘记了怎么办? 今天准备再学习一下linux操作系统,由于之前已经安装过vaware和linux(redhat),所以这次认为不 ...
- java 文件过滤器 java.io.FilenameFilter
File 类里有方法: String[] list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录. File ...
- linux主次编号
字符设备通过文件系统中的名子来存取. 那些名子称为文件系统的特殊文件, 或者设备文 件, 或者文件系统的简单结点; 惯例上它们位于 /dev 目录. 字符驱动的特殊文件由使用 ls -l 的输出的第一 ...