[jzoj 3056] 数字 {容斥+dp}

版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88363554

题目

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。


解题思路

ANS=前n位之和与后n位之和相等的方案数+奇数位之和与偶数位之和相等的方案数-前n位之和与后n位之和相等且奇数位之和与偶数位之和相等的方案数


代码

#include<cstdio>
#include<algorithm>
#include<string>
#define rep(i,x,y) for (register int i=x;i<=y;i++)
#define ll long long 
using namespace std; 
const ll mod=999983; 
ll n,a[11],tot,ans,f[1001][9010],q,w,x,y; 
int main(){
	scanf("%lld\n",&n); x=n/2,y=n-n/2; f[0][0]=1; 
	char c=getchar(); 
	while (isdigit(c)) a[++tot]=c-48,c=getchar();
	rep(i,0,n-1) rep(j,0,n*9) rep(k,1,tot)
	 f[i+1][j+a[k]]=(f[i+1][j+a[k]]+f[i][j])%mod; 
	rep(i,0,n*9) ans+=f[n][i]*f[n][i]*2%mod; 
	rep(i,0,x*9) q+=f[x][i]*f[x][i]%mod; 
	rep(i,0,y*9) w+=f[y][i]*f[y][i]%mod; 
	printf("%lld",(ans-q*w%mod)%mod); 
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/88363554