[题解] 不同的数列

题目

题目内容

我们有一个长度无穷的数列\(a[i]\),其中初始的时候只有数列前n项可能不为0,从第n+1项开始都为0。
我们可以做如下操作任意次。
选择一个\(i\)满足\(a[i]>0\)\(a[i+1]>0\), 然后将\(a[i]\)\(1\)\(a[i+1]\)\(1\)\(a[i+2]\)\(1\)
我们现在想要知道,通过任意次做这个操作,能得到多少种不同的数列。
两个数列不同当且仅当这两个数列存在一个对应位置上的数不同。
答案非常大,输出答案对\(1000000007\)取模。
(注意这个不同数列的个数要包括初始的数列,可通过样例2理解)

输入格式

第一行一个整数n。
第二行n个整数,第i个整数代表a[i]。

输出格式

输出一行一个整数表示方案数对1000000007取模的结果。

数据范围

\(n\le 50,0\le a[i]\le 50\)

分析

状态设计

考虑最最最最最暴力的dp状态设计,\(dp[a_i][a_{i+1}]...[a_j]\)表示对于数列\({a_i,a_{i+1},...,a_{j-1},a_j,0,0,0,...}\)的答案。
发现\(dp[a_i][a_{i+1}][a_{i+2}][a_{i+3}]...[a_j]\)可以转移到\(dp[a_i-k][a_{i+1}-k][a_{i+2}+k][a_{i+3}]...[a_j]\)
其中,从\(a_{i+3}\)\(a_j\)都没有变化,且为原数列\(a\)中连续的一段数,于是考虑优化。
\(dp[x][y][z][k]\)表示对于数列\({x,y,z,a_{k},a_{k+1},...,a_{n-1},a_{n},0,0,0,...}\)的答案。

状态转移方程和边界条件

边界条件:

  • if(x>y) dp[x][y][z][k]=dp[y][y][z][k]\(x>y\),每次\(x-1,y-1,z+1\),直到\(y=0\),此时\(x\)的值对答案没有影响。下面讨论中默认\(x\le y\)
  • if(k>n) dp[x][y][z][k]=dp[x][y][z][n+1] 对于任意的\(k\),\(k>n\)\(dp[x][y][z][k]\)都表示了数列\({x,y,z,0,0,0,...}\)的答案。
  • 待完善

转移方程:

\[dp[x][y][z][k]=\sum_{i=0}^{x}dp[y-i][z+i][a[k]][k+1] \]

状态设计的优化

上述方案显然会TLE,于是考虑优化。
注意到dp数组是四维的,相对较大。考虑改为三维。
显然第四维非常重要不能删,所以应把前三维维护三个数改为用两维维护两个数。
\(dp[x][y][k]\)表示对于数列\({x,y,a_{k},a_{k+1},...,a_{n-1},a_{n},0,0,0,...}\)的答案。
下面讨论问什么只维护两个数是可行的

  1. 由转移方程可以看出每次转移后考虑答案的区间会向右移动1,所以虽然操作对三个数有效,但区间向右平移后第三个数变成了第二个。
  2. 之所以最后一维的k可以表示\({a_{k},a_{k+1},...,a_{n-1},a_{n},0,0,0,...}\),是因为他们都是原数列中的数。第三个数在修改前也是原数列中的数所以可以用k表示

同样的原因也可以发现我们至少要维护一个数

  1. 只维护一个数的话根本无法得知当前位置可以进行的操作次数
  2. 只维护第\(i\)个数时,由于在\(i-1\)处的操作(即a[i-1]-1,a[i]-1,a[i+1]+1),第\(i+1\)个数可能不是原数组中的数,所以不能用k表示

新的状态转移方程和边界条件

暂缺

DP数组的大小分析

\[dp[x][y][k] \]

由边界条件2可知,第三维大小为 \(n+2\)
显然第一、二维的大小为数列中数的最大值。
数列中数的初始最大值为50,数列非零位最长长度为50,欲求若干次操作后最大值的上界,不妨假设

  • 初始数列为\({50,50,50,...,50,50,0,0,0,...}\) (50个50)
  • 支持操作A:使\(a_{i-1}-1,a_{i}+\frac{1}{2}\)
  • 支持操作B:使\(a_{i+2}-1,a_{i}+\frac{1}{2}\)
    显然,由上述假设得到的答案大于等于若干次操作后最大值
    \(a_{49},a_{48}\)\(a_{50}\)的贡献为\(\frac{1}{2}(50+50)\)
    \(a_{47},a_{46}\)\(a_{50}\)的贡献为\(\frac{1}{4}(50+50)\)
    \(a_{45},a_{44}\)\(a_{50}\)的贡献为\(\frac{1}{8}(50+50)\)
    ...
    于是第一、二维的大小为

\[50+\frac{1}{2}(50+50)+\frac{1}{4}(50+50)+\frac{1}{8}(50+50)+... \]

代码

posted @ 2021-02-07 00:49  _Veritas  阅读(120)  评论(0)    收藏  举报