2021.8.10提高B组模拟2T4 数字(dp)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.10提高B组模拟2T4 数字(dp)相关的知识,希望对你有一定的参考价值。

数字

题目大意

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

  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的字符串,表示给定的数字集合。

2
0987654321

输出样例

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

1240

题目数据

对于20%的数据,n≤7。

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

解题思路

这题就是 dp

f i , j f_i,_j fi,j为长度为 i,和为 j 的方案数

可得 f i , j = f i , j + f i   −   1 , j   −   a   [   k   ] f_i,_j=f_i,_j + f_i~_-~_1,_j~_-~_a~_[~_k~_] fi,j=fi,j+fi  1,j  a [ k ]a数组 为 数字集合S中的所有数字

最后答案就是分别符合

它 前 n 位 之 和 与 后 n 位 之 和 相 等 它前n位之和与后n位之和相等 nn 它 奇 数 位 之 和 与 偶 数 位 之 和 相 等 它奇数位之和与偶数位之和相等 情况的

去 两种情况都符合的

注:开 long long 和 随时Mod

AC代码

#include<iostream>
#include<cstdio>
using namespace std;
const long long Mod=999983;
long long a[15];
long long n,ans1,ans2,ans3,f[1005][10005];
string s;
int main()
{
	scanf("%lld",&n);
	cin>>s;
	long long len=s.size();
	for(long long i=0;i<len;i++)
		a[i]=s[i]-48;
	f[0][0]=1ll;
	for(long long i=1;i<=n;i++)//dp
		for(long long j=0;j<=i*9;j++)
			for(long long k=0;k<len;k++)
				if(j>=a[k])
					f[i][j]=(f[i][j]+f[i-1][j-a[k]])%Mod;
	for(long long i=0;i<=n*9;i++)//求出分别符合两种情况的方案数
		ans1=(ans1+2*f[n][i]*f[n][i]%Mod)%Mod;
	for(long long i=0;i<=(n/2)*9;i++)//求两种情况都符合的方案数
		ans2=(ans2+f[n/2][i]*f[n/2][i]%Mod)%Mod;
	for(long long i=0;i<=(n-n/2)*9;i++)//同上一个for
		ans3=(ans3+f[n-n/2][i]*f[n-n/2][i]%Mod)%Mod;
	printf("%lld",((ans1-ans2*ans3%Mod)%Mod+Mod)%Mod);//求答案
	return 0;
}

谢谢

以上是关于2021.8.10提高B组模拟2T4 数字(dp)的主要内容,如果未能解决你的问题,请参考以下文章

2021.8.10提高B组模拟2T3 比赛(二分)(贪心—前缀和)

2021.8.10提高B组模拟2T1 单峰(快速幂)

2021.8.10提高B组模拟2T1 单峰(快速幂)

2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)

2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)

2021.8.10提高B组模拟2T3 比赛(二分)(贪心—前缀和)