POJ 2279 Mr. Youngs Picture Permutations

问题描述
有N个学生合影,站成左端对齐的 k排,每排分别有 N1,N2,N3,N4,……Nk个人,第一排站在最后面,第k排站在最前面。学生的身高各不相同,把他们的升高依次标记为1,2,……N。在合影时要求每一排从左到右身高递减,每一列从前到后也递减,问一共有多少种合影位置方案。
输入样例
3
3 2 1
输出样例
16

数据范围
N<=30,k<=5
题解
考虑按照顺序插入学生,即从大到小的顺序。所以每一个学生要进入就必须放在右端或下端,对于插入对象为一行时,即每一个同学插入某一行,该行应满足,未满,当前人数小于前一行的人数或者是第一行。所以可以以每行的人数建立状态。
f[x1][x2][x3][x4][x5]表示第一行有x1个人…… 的方案数。当插入一人到一行中时,这一维+1 方案数*2;
code

#include<bits/stdc++.h>
 using namespace std;
int n;
int a[100];
unsigned int f[31][31][31][31][31];
void work()
{
  f[0][0][0][0][0]=1;
  int a1=a[1],a2=a[2],a3=a[3],a4=a[4],a5=a[5];
  for(int x1=0;x1<=a1;x1++)
   for(int x2=0;x2<=a2;x2++)
    for(int x3=0;x3<=a3;x3++)
     for(int x4=0;x4<=a4;x4++)
      for(int x5=0;x5<=a5;x5++)
      {
      	if(x1<a1) f[x1+1][x2][x3][x4][x5]+=f[x1][x2][x3][x4][x5];
        if(x2<a2 && x2<x1) f[x1][x2+1][x3][x4][x5]+=f[x1][x2][x3][x4][x5];
      	if(x3<a3 && x3<x2) f[x1][x2][x3+1][x4][x5]+=f[x1][x2][x3][x4][x5];
      	if(x4<a4 && x4<x3) f[x1][x2][x3][x4+1][x5]+=f[x1][x2][x3][x4][x5];
      	if(x5<a5 && x5<x4) f[x1][x2][x3][x4][x5+1]+=f[x1][x2][x3][x4][x5];
	  }
   printf("%lld\n",f[a1][a2][a3][a4][a5]);
} 
int main()
{
  freopen("i.in","r",stdin);
  freopen("i.out","w",stdout);
  while(scanf("%d",&n)!=EOF)
  {
    if(n==0) break;
    memset(a,0,sizeof(a));
  	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  	work();
  }
  return 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值