Mr. Young’s Picture Permutations Page265 线性dp
1.一开始直接建了一个30^5的dp数组,爆空间了,然后用map+哈希处理一下,题解用的是dp[maxn][maxn/2][maxn/3][maxn/4][maxn/5],因为队伍的人数限制
a
1
>
=
a
2
>
=
a
3
>
=
a
4
>
=
a
5
a_1>=a_2>=a_3>=a_4>=a_5
a1>=a2>=a3>=a4>=a5,且
a
1
+
a
2
+
a
3
+
a
4
+
a
5
≤
30
a_1+a_2+a_3+a_4+a_5\leq 30
a1+a2+a3+a4+a5≤30,所以这么优化更简单一些
2.如果少于五组,就将其定义为0,方便
代码:
int N[7],k;
int qpow(int a,int b){int res=1;while(b){if (b&1)res=res*a;a*=a;b>>=1;}return res;}
int Hash(int a,int b,int c,int d,int e){return a*qpow(31,4)+b*qpow(31,3)+c*qpow(31,2)+d*qpow(31,1)+e;}
map<int,ll> M;
ll solve()
{
rep(a,0,N[1])
{
rep(b,0,N[2])
{
rep(c,0,N[3])
{
rep(d,0,N[4])
{
rep(e,0,N[5])
{
int x=Hash(a,b,c,d,e);
int x1=Hash(a+1,b,c,d,e);
int x2=Hash(a,b+1,c,d,e);
int x3=Hash(a,b,c+1,d,e);
int x4=Hash(a,b,c,d+1,e);
int x5=Hash(a,b,c,d,e+1);
if (a<N[1])M[x1]+=M[x];
if (a>b&&b<N[2])M[x2]+=M[x];
if (b>c&&c<N[3])M[x3]+=M[x];
if (c>d&&d<N[4])M[x4]+=M[x];
if (d>e&&e<N[5])M[x5]+=M[x];
}
}
}
}
}
int x6=Hash(N[1],N[2],N[3],N[4],N[5]);
return M[x6];
}
int main()
{
while(~scanf("%d",&k)&&k)
{
M.clear();M[0]=1;
rep(i,1,k)scanf("%d",&N[i]);
rep(i,k+1,5)N[i]=0;
WW(solve());
}
return 0;
}