POJ2279 Mr Young's Picture Permutations

描述: 有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前。
学生身高依次是1…N。在合影时候要求每一排从左到右递减,每一列从后面到前也递减,一共有多少总方案
输入
每组测试数据包含两行。第一行给出行数k。

第二行包含从后到前(n1,n2,…,nk)的行的长度,作为由单个空格分隔的十进制整数。

问题数据以0结束。

N<=30, k<=5;

输出 输出每组数据的方案数

样例输入
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

     用一个k元组来表示每一行已经确定的人数即可描述一个状态,进行转移即可。

  tip:从本题中可知,设计动态规划的状态转移方程不一定要以如何计算出一个状态的形式给出,也可以考虑用一个已知的状态更新后续阶段的状态

 #include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
long long dp[][][][][];//空间注意计算,否则会开爆(31,31/2,31/3...)
//f(a1,a2,a3,a4,a5)表示第i层有a[i]个人时的方案数
int k,num[];
int main()
{
while(scanf("%d",&k) && k)
{
memset(dp,,sizeof(dp));
memset(num,,sizeof(num));
for(int i= ; i<=k ; i++) scanf("%d",&num[i]);
dp[][][][][]=;
for(int i= ; i<=num[] ; i++)
{
for(int j= ; j<=num[] ; j++)
{
for(int k= ; k<=num[] ; k++)
{
for(int l= ; l<=num[] ; l++)
{
for(int p= ; p<=num[] ; p++)
{
if(i+<=num[])
dp[i+][j][k][l][p]+=dp[i][j][k][l][p];
if(j+<=num[]&&j<i)
dp[i][j+][k][l][p]+=dp[i][j][k][l][p];
if(k+<=num[]&&k<j&&k<i)
dp[i][j][k+][l][p]+=dp[i][j][k][l][p];
if(l+<=num[]&&l<k&&l<j&&l<i)
dp[i][j][k][l+][p]+=dp[i][j][k][l][p];
if(p+<=num[]&&p<l&&p<k&&p<j&&p<i)
dp[i][j][k][l][p+]+=dp[i][j][k][l][p]; }
}
}
}
}
printf("%lld\n",dp[num[]][num[]][num[]][num[]][num[]]);
}
return ;
}
  • 法二:(数学解法)杨氏矩阵和勾长公式

   转载:巨佬博客

杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件:
(1)如果格子(i,j)没有元素,则它右边和上边的相邻格子也一定没有元素。
(2)如果格子(i,j)有元素a[i][j] a[i][j]a[i][j],则它右边和上边的相邻格子要么没有元素,要么有元素且比a[i][j] a[i][j]a[i][j]大。
1 ~ n所组成杨氏矩阵的个数可以通过下面的递推式得到:

如图就是n=3时的杨氏矩阵。

下面介绍一个公式,那就是著名的钩子公式。
对于给定形状,不同的杨氏矩阵的个数为:n!除以每个格子的钩子长度加1的积。其中钩子长度定义:每个格子右边的格子数和它上边的格子数之和。

  代码:

 #include <cstdio>
#include <iostream>
#include <cstring>
using namespace std; inline int gcd(int a,int b)
{
return (b==)?a:gcd(b,a%b);
}
int d[],num[];
int n;
int main()
{
while(scanf("%d",&n)&&n)
{
int tot=;
memset(num,,sizeof(num));
for(int i= ; i<=n ; i++) scanf("%d",&d[i]);
for(int i=n ; i>= ; i--)
for(int j= ; j<=d[i] ; j++)
{
tot++;
for(int k=i+ ; k<=n ; k++)
if(d[k]>=j) num[tot]++;
else break;
num[tot]+=d[i]-j+;
}
long long t1=,t2=;
for(int i= ; i<=tot ; i++)
{
t1*=i; t2*=num[i];
int t=gcd(t1,t2);
t1/=t,t2/=t;
}
printf("%lld\n",t1/t2);
}
return ;
}

POJ2279 Mr Young's Picture Permutations的更多相关文章

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

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

  2. 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 ...

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

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

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

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

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

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

  6. Mr. Young's Picture Permutations

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

  7. 【杨氏矩阵+勾长公式】POJ 2279 Mr. Young's Picture Permutations

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

  8. [POJ 2279] Mr. Young's Picture Permutations

    [题目链接] http://poj.org/problem?id=2279 [算法] 杨氏矩阵与勾长公式 [代码] #include <algorithm> #include <bi ...

  9. POJ P2279 Mr. Young's Picture Permutations 题解

    每日一题 day14 打卡 Analysis 五维dpf[a1,a2,a3,a4,a5]表示各排从左端起分别占了a1,a2,a3,a4,a5个人时合影方案数量然后我们枚举a1,a2,a3,a4,a5从 ...

随机推荐

  1. Web内容回顾

    -----------------siwuxie095 Java EE 三层结构 1.Web 层:Struts2 框架 2.Service 层:Spring 框架 3.DAO 层:Hibernate ...

  2. Java-CSV文件读取

    import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import ja ...

  3. 117. Populating Next Right Pointers in Each Node II 计算右边的附属节点

    [抄题]: Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNod ...

  4. #error用法

    #error命令是C/C++语言的预处理命令之一,当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息. 语法: #error [用户自定义的错误消息] 注:上述语法成份中的方括号 ...

  5. pcl知识

    1.pcl/io/pcd_io.h pcl/io/ply_io.h pcl::PLYReader reader; pcl::PCDWriter pcdwriter; 读取ply pcd 2.voidl ...

  6. Web测试实践-任务进度-Day02

    小组成员 华同学.郭同学.覃同学.刘同学.穆同学.沈同学 任务进度 在经过任务分配阶段后,大家都投入到了各自的任务中,以下是大家今天任务的进度情况汇总. 华同学 & 刘同学(任务1) 1.对爱 ...

  7. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 12: ordinal not in range(128)问题解决

    今天在验证字符串是否包含的时候报错:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 12: ordinal n ...

  8. CodeForces 681C Heap Operations (模拟题,优先队列)

    题意:给定 n 个按顺序的命令,但是可能有的命令不全,让你补全所有的命令,并且要求让总数最少. 析:没什么好说的,直接用优先队列模拟就行,insert,直接放入就行了,removeMin,就得判断一下 ...

  9. SQLServer学习-- Microsoft SQL Server 2008 Management Studio Express

    Microsoft SQL Server 2008 Management Studio Express is a free, integrated environment for accessing, ...

  10. Redis缓存相关

    Redis缓存服务搭建及实现数据读写 RedisHelper帮助类 /// <summary> /// Redis 帮助类文件 /// </summary> public cl ...