高中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表示偶数位):


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



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

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值