题目大意:
题目链接:http://poj.org/problem?id=2279
个学生站成排,每排分别有名学生。要求每排的学生的身高单调递增,而每一排的同位的同学的身高单调递减。求总的方案数。
思路:
排数最多五排,所以可以考虑五维。
设表示第一排站人,第二排站人第五排站人的总方案数,那么由于人是从高到矮读入,所以,第行的人影响到第行的人,而每一行之间又有条件限制(单调性),所以状态转移方程也很容易得到了。
最终答案在中。
但是!
这样设定五维数组会!!!
所以我设了五维的储存答案。。。(时间换空间)
代码:
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
unsigned int n,k,peo[6],a,b,c,d,e;
map<pair<pair<pair<pair<unsigned int,unsigned int>,unsigned int>,unsigned int>,unsigned int>,unsigned int> f;
//五维map,相当于f[31][31][31][31][31]
int main()
{
while (cin>>n) //多组数据
{
if (!n) return 0;
peo[1]=peo[2]=peo[3]=peo[4]=peo[5]=0; //初始化
for (unsigned int i=1;i<=n;i++)
cin>>peo[i];
f.clear(); //清空f数组
//相当于memset(f,0,sizeof(0));
f[make_pair(make_pair(make_pair(make_pair(0,0),0),0),0)]=1; //初始化
for (a=0;a<=peo[1];a++)
for (b=0;b<=peo[2];b++)
for (c=0;c<=peo[3];c++)
for (d=0;d<=peo[4];d++)
for (e=0;e<=peo[5];e++) //枚举每一行的人数
{
k=f[make_pair(make_pair(make_pair(make_pair(a,b),c),d),e)];
if (a<peo[1]) f[make_pair(make_pair(make_pair(make_pair(a+1,b),c),d),e)]+=k;
if (b<peo[2]&&b<a) f[make_pair(make_pair(make_pair(make_pair(a,b+1),c),d),e)]+=k;
if (c<peo[3]&&c<b) f[make_pair(make_pair(make_pair(make_pair(a,b),c+1),d),e)]+=k;
if (d<peo[4]&&d<c) f[make_pair(make_pair(make_pair(make_pair(a,b),c),d+1),e)]+=k;
if (e<peo[5]&&e<d) f[make_pair(make_pair(make_pair(make_pair(a,b),c),d),e+1)]+=k;
}
cout<<f[make_pair(make_pair(make_pair(make_pair(peo[1],peo[2]),peo[3]),peo[4]),peo[5])]<<endl;
//转移方程,每一行一个,从第二行开始受到前面一行影响,所以要多一个判断语句
}
return 0;
}