[CSP-J2022 山东] 吟诗题解

题目背景

受疫情影响,山东省取消了 CSP-J 2022 认证活动,并于次年三月重新命题,在省内补办比赛。

题目描述

"文章本天成,妙手偶得之。"

吟诗是表达情怀的常用手段,战争落下了帷幕,常年的军旅生活使得小虾米喜欢上了豪放派的诗歌。

这一天,小虾米突然想吟诗了。著名的豪放派诗人苏轼有“老夫聊发少年狂,左牵黄,右擎苍。”的豪放,又有“十年生死两茫茫,不思量,自难忘。”的悲怆。小虾米心向往之,于是也想用《江城子》词牌名作诗。

小虾米想作出能流传千古的诗,根据经验,如果一首诗存在妙手就能流传千古。

具体来说,一首 N 个字的诗,每个字可以用 1 到 10 之间的某个正整数来表示。同时存在三个正整数 X,Y,Z(1≤X≤7,1≤Y≤5,1≤Z≤5),如果诗中出现了三个连续的片段使得第一个片段之和为 X,第二个片段之和为 Y,第三个片段之和为 Z,则小虾米认为这首诗出现了妙手

即长度为 n 的序列 a1​,a2​,…an​(1≤ai​≤10),如果存在 i,j,k,l(1≤i<j<k<l≤n) 使得ai​+ai+1​+…aj−1​=X 且 aj​+aj+1​+…ak−1​=Y 且 ak​+ak+1​+…al−1​=Z 同时成立,则认为序列出现了妙手(注:第二个片段紧接第一个片段,第三个片段紧接第二个片段)。

举例来说,如果 N=7,X=7,Y=3,Z=3,则所有长度为 7 的序列中,很显然共有 107 种序列,其中一种序列 [1,5,2,2,1,3,4] 出现了妙手,因为存在三个连续的区间 [2,3]、[4,5]、[6,6] 满足它们的和分别为 X=7,Y=3,Z=3。

小虾米想知道在给定 N,X,Y,Z 的前提下(共计 10n 种序列,即共 10n 种诗),计算有多少种存在妙手的诗,请你帮他计算出答案。

由于答案可能很大,请你将结果对 998244353 取模。

输入格式

一行,以空格隔开的 4 个正整数 N,X,Y,Z,分别表示序列长度和题目中 X,Y,Z 的值。

输出格式

一行,一个整数,表示答案对 998244353 取模的结果。

输入输出样例

输入 #1复制

3 2 3 3

输出 #1复制

1

输入 #2复制

4 7 5 5

输出 #2复制

34

输入 #3复制

23 7 3 5

输出 #3复制

824896638

说明/提示

样例一说明

在所有可能的序列中,只能构造出一种序列 [2,3,3] 满足题意,因此答案为 1。

数据范围

对于 30% 的数据,3≤N≤5;

对于 60% 的数据,3≤N≤20;

对于 100% 的数据,3≤N≤40,1≤X≤7,1≤Y≤5,1≤Z≤5。

附件下载

CSP-J2022入门组二轮补赛试题(山东).pdf1.58MB

思路

状压DP,动态规划 DP,枚举。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,x,y,z,ma,f[41][150005],op,lk=1,mod=998244353;
int main(){
    cin>>n>>x>>y>>z;
    ma=1<<(x+y+z);
    f[0][0]=1;
    for(int i=0;i<=n-1;i++){
        for(int j=0;j<=ma-1;j++){
            for(int k=1;k<=10;k++){
                op=((j<<k)+(1<<(k-1)))&(ma-1);
                if((op&(1<<(z-1)))&&(op&(1<<(y+z-1)))&&(op&(1<<(x+y+z-1)))){
                    
                }    
                else{
                    f[i+1][op]=(f[i+1][op]+f[i][j])%mod;
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        lk*=10;
        lk%=mod;
    }
    for(int i=0;i<=ma-1;i++){
        lk-=f[n][i];
        lk%=mod;
    }
    cout<<(lk+mod)%998244353ll<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值