2021.8.10提高B组模拟2T4 数字(dp)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.10提高B组模拟2T4 数字(dp)相关的知识,希望对你有一定的参考价值。
数字
题目大意
一个数字被称为好数字当他满足下列条件:
-
它有2*n个数位,n是正整数(允许有前导0)
-
构成它的每个数字都在给定的数字集合S中。
-
它前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位之和相等 它前n位之和与后n位之和相等 和 它 奇 数 位 之 和 与 偶 数 位 之 和 相 等 它奇数位之和与偶数位之和相等 它奇数位之和与偶数位之和相等 情况的
减去 两种情况都符合的
注:开 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组模拟2T2 祖孙询问(lca)(倍增)