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 ...
随机推荐
- 【调制解调】VSB 残留边带调幅
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录,代码已上传到 Github - ModulationAndDemodulation.本篇介绍 VS ...
- 现代C++(Modern C++)基本用法实践:N、其他零散的常用特性
概述 这一篇简单介绍一些其他的比较实用的特性,如果读者想了解现代C++的全部特性,参考:cpp reference 其他特性 预置和弃置函数default&delete 在 C++11 中引入 ...
- Blazor提取出Razor类库,没有css的class的智能提示
最开始从stackoverflow上找到了答案,有两种办法,但都不太理想 后来自己找了新的办法,其实很简单,把要用的css复制到Razor类库的wwwroot文件夹中,默认是不会复制到引用Razor类 ...
- 使用guestmount更改qcow2镜像内容
参考: 使用guestmount更改qcow2镜像内容 guestmount 安装 yum install libguestfs libguestfs-tools -y 使用 guestmount - ...
- node.js中kafka的封装和高并发消费限流优雅降级以及egg-kafka的封装说明
HI!,你好,我是zane,zanePerfor是一款我开发的一个前端性能监控平台,现在支持web浏览器端和微信小程序端. 我定义为一款完整,高性能,高可用的前端性能监控系统,这是未来会达到的目的,现 ...
- Java 生态需要新鲜的血液、需要狂飙的刺激。Solon v2.4.1 发布
Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...
- 王道oj/problem23
网址:oj.lgwenda.problem/23 代码: #define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include<stri ...
- 从module_init看内核模块
开篇 module_init是linux内核提供的一个宏, 可以用来在编写内核模块时注册一个初始化函数, 当模块被加载的时候, 内核负责执行这个初始化函数. 在编写设备驱动程序时, 使用这个宏看起来理 ...
- 使用 Rancher 安装 K8s 集群
舞台环境 Ubuntu 22.04.2 LTS Docker 24.0.2 2GB RAM或者更多 CPU 2核心或者更多 Rancher 2.6.9 测试环境中,我准备了两台 Ubuntu 服务器, ...
- embed简介
go embed 是 Go 1.16 中引入的特性,它允许将文件嵌入到 Go 代码中,以便在运行时访问这些文件.这对于将静态资源(如 HTML.CSS.JavaScript 文件)直接嵌入到 Go 二 ...