Jzoj 3056NOIP2012模拟10.27容斥DP数学数字

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jzoj 3056NOIP2012模拟10.27容斥DP数学数字相关的知识,希望对你有一定的参考价值。

【NOIP2012模拟10.27】数字

Link

Jzoj【3056】【NOIP2012模拟10.27】数字


题面

Description
一个数字被称为好数字当他满足下列条件:

  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。

Input

第一行一个数n。
接下来一个长度不超过10的字符串,表示给定的数字集合。

Output

一行一个数字表示合法的好数字的个数mod 999983。

Sample Input

2
0987654321

Sample Output

1240

Data Constraint

对于20%的数据,n≤7。
对于100%的.据,n≤1000,|S|≤10。


解题思路

设 f[i][j] 为 i 个位,和为 j 的方案数
这个随便求一下就好了, f [ i ] [ j ] + = f [ i − 1 ] [ j − a [ k ] ] f[i][j] += f[i-1][j-a[k]] f[i][j]+=f[i1][ja[k]]

问题转换一下(容斥),前半段和=后半段和的方案 + 奇数位和=偶数位和的方案数 - 两种都满足的方案
前半段和=后半段和的方案:f[n][i] ^ 2
奇数位和=偶数位和的方案数:
其实可以发现奇数位全部移到左边,偶数位全部移到右边,然后又变成了前半段和=后半段和的方案

两种都满足的方案:这个就有点猥琐了
a为前半段奇数位和,b为前半段偶数位和,c为后半段奇数位和,d为后半段偶数位和
两种都满足

  1. a + b = c + d
  2. a + c = b + d

得出b = c,a = d
然后列几个数字发现,b = c和a = d的方案数是不一样的
因为如果 n 是个奇数,那么前半段的奇数位的个数 和 后半段的偶数位个数会更多
b = c方案数 * a = d方案数就是两种都满足的方案数


Code

#include <bits/stdc++.h>
#define P 999983
#define ll long long

using namespace std;

char a[10];
int n;
ll f[1010][9010], ans, k1, k2, maxn;

int main() {
	scanf("%d", &n);
	scanf("%s", a + 1);
	int la = strlen(a + 1);
	for(int i = 1; i <= la; i ++)
		maxn = max(maxn, (ll)(a[i] - '0'));
	f[0][0] = 1;
	for(int i = 1; i <= n; i ++)
		for(int j = 0; j <= n * maxn; j ++)
			for(int k = 1; k <= la; k ++)
				if(j >= (int)(a[k] - '0'))
					f[i][j] = (f[i][j] + f[i - 1][j - (int)(a[k] - '0')]) % P;
	for(int i = 0; i <= n * maxn; i ++)
		ans = (ans + 2 * f[n][i] * f[n][i] % P) % P;
	for(int i = 0; i <= (n + 1) / 2 * maxn; i ++)
		k1 = (k1 + f[(n + 1) / 2][i] * f[(n + 1) / 2][i] % P) % P;  //a = d的方案数
	for(int i = 0; i <= n / 2 * maxn; i ++)
		k2 = (k2 + f[n / 2][i] * f[n / 2][i] % P) % P;  //b = c的方案数
	ans = (ans - k1 * k2 % P + P) % P;  //因为可能是负数所以先+P
	printf("%lld", ans);
}

以上是关于Jzoj 3056NOIP2012模拟10.27容斥DP数学数字的主要内容,如果未能解决你的问题,请参考以下文章

Jzoj 3054NOIP2012模拟10.27倍增祖孙询问

[jzoj]2938.NOIP2012模拟8.9分割田地

10.27 noip模拟试题(moring)

10.27 noip模拟试题(afternoon)(跪在游戏玩少了2333)

Jzoj4742NOIP2016提高A组模拟9.2快速幂单峰

jzoj4624NOIP2016A组模拟7.13KMP数学字符串匹配