poj2279
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 5841 | Accepted: 1860 |
Description
X X X X X
X X X
X X X
X
In addition, Mr. Young wants the students in each row arranged so
that heights decrease from left to right. Also, student heights should
decrease from the back to the front. Thinking about it, Mr. Young sees
that for the 12-student example, there are at least two ways to arrange
the students (with 1 as the tallest etc.):
1 2 3 4 5 1 5 8 11 12
6 7 8 2 6 9
9 10 11 3 7 10
12 4
Mr. Young wonders how many different arrangements of the students
there might be for a given arrangement of rows. He tries counting by
hand starting with rows of 3, 2 and 1 and counts 16 arrangements:
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
Mr. Young sees that counting by hand is not going to be very
effective for any reasonable number of students so he asks you to help
out by writing a computer program to determine the number of different
arrangements of students for a given set of rows.
Input
input for each problem instance will consist of two lines. The first
line gives the number of rows, k, as a decimal integer. The second line
contains the lengths of the rows from back to front (n1, n2,..., nk) as
decimal integers separated by a single space. The problem set ends with a
line with a row count of 0. There will never be more than 5 rows and
the total number of students, N, (sum of the row lengths) will be at
most 30.
Output
output for each problem instance shall be the number of arrangements of
the N students into the given rows so that the heights decrease along
each row from left to right and along each column from back to front as a
decimal integer. (Assume all heights are distinct.) The result of each
problem instance should be on a separate line. The input data will be
chosen so that the result will always fit in an unsigned 32 bit integer.
Sample Input
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
Sample Output
1
1
16
4158
141892608
9694845
题目不难,有几个值得学习的地方(就是我不会的地方)
首先是这个思考方式,也就是对这个问题特征的分析
我们要计算所有的方式,计数类题目基本都是这种套路,要么是直接用数学大力分析一手,然后各种组合数乘法原理加法原理
要么就是根据这个题目的特别性进行一个稍微类似枚举的过程
对于这个,直接枚举所以可能性自然是非常的不可行的,连样例都不可能过
我们考虑一个构造的过程,假设我们已经有了一个不完整但是暂时合法的组合,我们考虑给它加上一个数字
可以发现,如果这个是合法的,那么它从左上到右下的数字应该是在逐渐增大的(并不严谨,但是可以先这样理解一下)
那么我们就从左上方开始构造,因为可以发现1永远要在左上角,这个应该是容易证明的
我们就从这个确定的1开始,保证这个方阵合法的情况下,向着左边和下边进行构造
我们试着把所有数字从1开始由小到大逐渐放进这个方阵中,为了保证这个方阵始终合法,我们需要考虑一下应该按照什么样子的规则来进行
首先,每一个数字下面的的数字肯定是要比这个数字大的,而我们在构造的时候是从小到大的,所以只要后放就更大
也就是说,一个数字右边或者是下面的数字肯定是要在这个数字后放的。
也就是说,在一个数字被放下前,它的上面和左边的数字肯定是已经被放好的。
利用这个规则,我们就可以开始dp了
设f[a][b][c][d][e]为当第一排有a个人,第二排有b个人,第三排有c个人·····时的合法方案数
用k[i]表示第i排最多的人数
转移(也许算是递推吧?)的方程就是
对于第一排,当a<k1时,让f[a+1][b][c][d][e]+=f[a][b][c][d][e]
对于下面的则是,当b<k2且b<a,让f[a][b+1][c][d][e]+=f[a][b][c][d][e]
剩下的也是以此类推
附上代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <string.h>
#define ll long long
using namespace std;
inline int read() {
char c=getchar();int a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int k[6],n,tot;
int main()
{
while(n=read())
{
if(n==0)break;
tot=0;
memset(k,0,sizeof(k));
for(int i=1;i<=n;i++)
k[i]=read(),tot+=k[i];
unsigned ll f[k[1]+1][k[2]+1][k[3]+1][k[4]+1][k[5]+1];
memset(f,0,sizeof(f));
f[0][0][0][0][0]=1;
for(int k1=0;k1<=k[1];k1++)
{
for(int k2=0;k2<=k[2];k2++)
{
for(int k3=0;k3<=k[3];k3++)
{
for(int k4=0;k4<=k[4];k4++)
{
for(int k5=0;k5<=k[5];k5++)
{
if(k1<k[1])f[k1+1][k2][k3][k4][k5]+=f[k1][k2][k3][k4][k5];
if(k2<k1&&k2<k[2])f[k1][k2+1][k3][k4][k5]+=f[k1][k2][k3][k4][k5];
if(k3<k2&&k3<k[3])f[k1][k2][k3+1][k4][k5]+=f[k1][k2][k3][k4][k5];
if(k4<k3&&k4<k[4])f[k1][k2][k3][k4+1][k5]+=f[k1][k2][k3][k4][k5];
if(k5<k4&&k5<k[5])f[k1][k2][k3][k4][k5+1]+=f[k1][k2][k3][k4][k5];
}
}
}
}
}//我在干什么?
cout<<f[k[1]][k[2]][k[3]][k[4]][k[5]]<<endl;
}
return 0;
}
这个空间真的是。。。
魔幻
这题主要是这个计数,我之前好像总结过?有点印象,但是已经过去太久了,忘记了。
一个主要的点就是,对于每一道题目,都要分析一下题目的特征或者说是特性,这是解题的关键,也是题目的难点(一般来说)
而这种加法来计数的,也就是这一类构造题目的一个解题方向
也是应该从中积累和学习到的东西
poj2279的更多相关文章
- POJ2279 Mr Young's Picture Permutations
POJ2279 Mr Young's Picture Permutations 描述: 有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前.学生身高依次是1… ...
- 【题解】POJ2279 Mr.Young′s Picture Permutations dp
[题解]POJ2279 Mr.Young′s Picture Permutations dp 钦定从小往大放,然后直接dp. \(dp(t1,t2,t3,t4,t5)\)代表每一行多少人,判断边界就能 ...
- 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 ...
- poj2279 线性dp
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using n ...
- POJ2279杨氏矩阵+钩子定理
题目:http://poj.org/problem?id=2279 有dp做法,但会MLE. dp的思想很好,是通过 “按身高由小到大往进放” 把 “身高小于” 的条件转化成 “放进去的先后” ,于是 ...
- poj2279排队——杨氏矩阵与钩子公式(DP爆内存)
题目:http://poj.org/problem?id=2279 书上的DP做法会爆内存,尝试写了一个,过了样例. 转载: 代码如下: #include<iostream> #inclu ...
- poj2279 Mr. Young's Picture Permutations[勾长公式 or 线性DP]
若干人左对齐站成最多5行,给定每行站多少个,列数从第一排开始往后递减.要求身高从每排从左到右递增(我将题意篡改了便于理解233),每列从前向后递增.每个人身高为1...n(n<=30)中的一个数 ...
- OJ题目分类
POJ题目分类 | POJ题目分类 | HDU题目分类 | ZOJ题目分类 | SOJ题目分类 | HOJ题目分类 | FOJ题目分类 | 模拟题: POJ1006 POJ1008 POJ1013 P ...
- 常规DP专题练习
POJ2279 Mr. Young's Picture Permutations 题意 Language:Default Mr. Young's Picture Permutations Time L ...
- 0x51 线性DP
数据结构没什么好写的..分块和整体二分还有点分学得很懂..果然我还是比较适合这些东西 poj2279 奇怪题,我的想法就是五维记录最边上的一斜排,会M,结果的的确确是锻炼思维的,正解并不是DP2333 ...
随机推荐
- 【EF Core】实体的主、从关系
假设有以下两个实体: public class Student { public int StuID { get; set; } public string? Name { get; set; } p ...
- GGTalk 开源即时通讯系统源码剖析之:数据库设计
自从<开源即时通讯GGTalk 8.0发布,增加Linux客户端,支持在统信UOS.银河麒麟上运行!>一文在博客园发布后,有园友联系我QQ,说能不能整理个更系统更详细地介绍GGTalk源码 ...
- Cisco命令中login和login local的区别
login是开启远程登录密码验证,login local不但要求密码,还要求提供用户名 如果同时设置login和login local,login local有效 (config-line)#line ...
- spring cloud zuul实践
一. 描述 Spring Cloud Zuul是基于Netflix开源的Zuul项目构建而成,它作为微服务架构中的网关服务,主要用于实现动态路由.负载均衡和请求过滤等功能. 动态路由:Zuul根据预设 ...
- Spring-Bean的依赖注入的数据类型
Spring-Bean的依赖注入的数据类型 除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入 数据的三种数据类型 普通数据类型 引用数据类型 集合数据类型 普通数据类型 public ...
- 这可能是前端处理excel最好的工具了
大家好,我是程序视点的小二哥! 今天小二哥要分享的是一个纯前端实现读取和导出excel文件的工具库:ExcelJS ExcelJs 简介 功能十分简单: 读取,操作并写入电子表格数据和样式到 XLSX ...
- 2021-7-12 VUE的组件认识
VUE组件简单实例 <!DOCTYPE html> <html> <head> <title> </title> </head> ...
- 借助 mkcert 和批处理命令生成局域网证书
借助 mkcert 和批处理命令生成局域网证书 自动获取ipv4,一键生成很方便 cd /d %~dp0 ipconfig |find "IPv4" > ipv4 set / ...
- 加密解决HTTP协议带来的安全问题
HTTP协议默认是采取明文传输的,容易被中间人窃听.拦截.篡改,存在安全隐患. 常见提高安全性的方法是对通信内容进行加密,再进行传输,常见的加密方式有 不可逆加密:单向散列函数 可逆加密:对称加密.非 ...
- python将print的打印内容保存到日志
将python程序中的所有打印内容都输出到日志文件中,在程序执行完成后,方便查询程序运行过程是否出现异常. 1. 将打印内容输出到日志文件 1.1 代码实现: sys.stdout = open('s ...