Mr. Young's Picture Permutations

题目大意:

给定N个学生,k排,每排分别有N1,N2,N3……Nk
合影时要求每一排从左到右身高递减,每一列从后到前身高也递减,问一共有多少种安排合影位置的方案

解题思路:

五维dp
f[a1,a2,a3,a4,a5]表示各排从左端起分别占了a1,a2,a3,a4,a5个人时合影方案数量
然后我们枚举a1,a2,a3,a4,a5从0开始到N1,N2……N5
若a1 < N1
若a2 < N2&a1 > a2
若a3 < N3&a2 > a3
……(以此类推)
额,这题还可以用一种我不会的数学解法:
“杨氏矩阵”+“勾长公式”
百度一下这个题目似乎用数学解法的人还挺多的

Accepted code:

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<iostream>
#define r(i,a,b) for(int i=a;i<=b;i++)
#define N 31
using namespace std;
int t,n[6];
inline void read(int &f) {
    f=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) f=(f<<3)+(f<<1)+c-48,c=getchar();
    return;
}

inline bool init(){
    read(t); if (t==0) return 0;
    r(i,1,t)
        read(n[i]);
    r(i,t+1,5) n[i]=0; return 1;
}


inline unsigned int dp() {
    unsigned int f[n[1]+1][n[2]+1][n[3]+1][n[4]+1][n[5]+1];
    memset(f,0,sizeof(f));
    f[0][0][0][0][0]=1;
    r(i1,0,n[1])
        r(i2,0,n[2])
            r(i3,0,n[3])
                r(i4,0,n[4])
                    r(i5,0,n[5]) {
                        if (i1<n[1])
                            f[i1+1][i2][i3][i4][i5]+=f[i1][i2][i3][i4][i5];
                        if (i2<n[2]&&i1>i2)
                            f[i1][i2+1][i3][i4][i5]+=f[i1][i2][i3][i4][i5];
                        if (i3<n[3]&&i2>i3)
                            f[i1][i2][i3+1][i4][i5]+=f[i1][i2][i3][i4][i5];
                        if (i4<n[4]&&i3>i4)
                            f[i1][i2][i3][i4+1][i5]+=f[i1][i2][i3][i4][i5];
                        if (i5<n[5]&&i4>i5)
                            f[i1][i2][i3][i4][i5+1]+=f[i1][i2][i3][i4][i5];
                    }
    return f[n[1]][n[2]][n[3]][n[4]][n[5]];
}


int main() {
    while(init())
        cout<<dp()<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值