问题描述
一个数字被称为好数字当他满足下列条件:1. 它有2*n个数位,n是正整数(允许有前导0)
2. 构成它的每个数字都在给定的数字集合S中。
3. 它前n位之和与后n位之和相等或者它奇数位之和与偶数位之和相等
例如对于n=2,S={1,2},合法的好数字有1111,1122,1212,1221,2112,2121,2211,2222这样8种。
已知n,求合法的好数字的个数mod 999983。
输入
第一行一个数n。
接下来一个长度不超过10的字符串,表示给定的数字集合。
输出
一行一个数字表示合法的好数字的个数mod 999983。
样例输入
2
0987654321
样例输出
1240
数据范围
对于20%的数据,n≤7。
对于100%的.据,n≤1000,|S|≤10。
本题所讲的除法皆为整除!
10分:
打表。。。
复杂度O(1)
20分:
直接暴力枚举2n位。。。
复杂度O(2n^|S|)
100分:
从数据上就可以看出这是一道DP题。。。
设F[i,j]表示长度为i且当前序列和为j时的方案数
设maxnum为S集合种最大的数字
初始化:F[0,0]=1
状态转移方程:F[i,j]=∑(F[i-1,j-S[k]]) (i=1~n j=0~maxnum*i k=1~|S|)
之后计算前后相等的方案数:∑F[n,i]^2 (i=0~maxnum*n)
接着计算奇偶位相等的情况。
例如有这样一种情况(X表示奇数位,Y表示偶数位):
可以把奇偶位连成两个两个序列
其实跟第一种方案数相同,所以我们只要把方案数*2就可以计算出两种方案的总和。
BUT——
方案是有重复的!
例如:
1221这个串,前后位和奇偶位都相等。
所以我们还要减去重复的方案数。
∑F[(n+1)/2,i]^2 (i=0~maxnum*(n+1)/2)
×
∑F[n/2,i]^2 (i=0~maxnum*n/2)
最后用之前所求的答案减去上面的结果就可以了。
复杂度O(n^2*maxnum*|S|) (实际上没有这么高)
提示:
因为最后减出的结果有可能会出现负数,所以在计算完重复的方案数后要先取一次余,最后答案加上999983再除。