杨老师的照相排列
传送门
题意就不讲了。
题解:我们根据约束条件将,问题分成五个小集合,每个集合代表这一排站的人数。我们的last(状态转移点)点是我们这一排的最后一个人站没站进来。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=35;
int f[N][N][N][N][N];
int s[N];
signed main()
{
int n;
while(cin>>n,n){
memset(s,0,sizeof s);
for(int i=1;i<=n;i++) cin>>s[i];
memset(f,0,sizeof f);
f[0][0][0][0][0]=1;
for(int a=0;a<=s[1];a++){
for(int b=0;b<=min(s[2],a);b++){
for(int c=0;c<=min(s[3],b);c++){
for(int d=0;d<=min(s[4],c);d++){
for(int e=0;e<=min(s[5],d);e++){
if(a&&a-1>=b) f[a][b][c][d][e]+=f[a-1][b][c][d][e];
if(b&&b-1>=c) f[a][b][c][d][e]+=f[a][b-1][c][d][e];
if(c&&c-1>=d) f[a][b][c][d][e]+=f[a][b][c-1][d][e];
if(d&&d-1>=e) f[a][b][c][d][e]+=f[a][b][c][d-1][e];
if(e) f[a][b][c][d][e]+=f[a][b][c][d][e-1];
}
}
}
}
}
cout<<f[s[1]][s[2]][s[3]][s[4]][s[5]]<<endl;
}
}