高中OJ3056【NOIP2012模拟10.27】数字

问题描述

    一个数字被称为好数字当他满足下列条件:
    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表示偶数位):

高中OJ3056【NOIP2012模拟10.27】数字_第1张图片

可以把奇偶位连成两个两个序列

高中OJ3056【NOIP2012模拟10.27】数字_第2张图片

高中OJ3056【NOIP2012模拟10.27】数字_第3张图片

其实跟第一种方案数相同,所以我们只要把方案数*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再除。

你可能感兴趣的:(OJ题解)