打卡信奥刷题(3466)用C++实现信奥题 P10528 [XJTUPC 2024] 崩坏:星穹铁道

P10528 [XJTUPC 2024] 崩坏:星穹铁道

题目背景

Corycle 喜欢玩一个由米哈游自主研发的一款回合制战斗游戏------《崩坏:星穹铁道》。这片银河中有名为「星神」的存在,他们造就现实,抹消星辰,在无数「世界」中留下他们的痕迹。你将由此探索新的文明,结识新的伙伴,在无数光怪陆离的「世界」与「世界」之间展开新的冒险。所有你想知道的,都将在群星中找到答案。

题目描述

在游戏《崩坏:星穹铁道》中,你的队伍里会有四名角色轮流行动,所有角色共享用于施放战技的战技点。当战斗开始时,你会获得 kkk 个战技点,且战技点的上限为 555 个。每个角色行动时可选择进行普通攻击或者施放战技,进行普通攻击时会为全队增加一个战技点,当战技点达到上限时也可以进行普通攻击,但是此时不回复战技点。角色施放战技需要消耗一个战技点,当没有战技点时只能进行普通攻击而不可释放技能。

Corycle 想成为星穹铁道高手,为此他需要对自己的配队了如指掌。由于角色有多种职业,同时为了方便对角色类型进行定位,他把角色的行动模式分为了三种类型:

  1. 当角色行动时,只会进行普通攻击。

  2. 当角色行动时,若有战技点不少于 111 则必定释放技能,否则进行普通攻击。

  3. 不对角色的行动进行限制。

现在 Corycle 开始了一场战斗,他想知道当队伍中的四名角色一共行动 nnn 次时,可能会有多少种不同的行动方案。我们称两个行动方案不同,当且仅当存在至少一个回合中,两个方案里角色行为不同。这个答案可能是一个很大的数,所以请将答案对 998244353998244353998244353 取模。

输入格式

输入第一行有两个正整数 nnnkkk (1≤n≤1×1018,0≤k≤51\le n\le 1\times 10^{18},0\le k\le 51n1×1018,0k5),表示总行动次数与初始战技点数,用空格隔开。

第二行有四个用空格隔开的正整数 a1,a2,a3,a4a_1,a_2,a_3,a_4a1,a2,a3,a4 (1≤a1,a2,a3,a4≤31 \le a_1,a_2,a_3,a_4 \le 31a1,a2,a3,a43),表示四名角色的行动模式类型。

输出格式

输出仅一个整数,表示不同的行动方案数。

输入输出样例 #1

输入 #1

12 1
2 3 2 1

输出 #1

1

输入输出样例 #2

输入 #2

8 5
2 1 1 3

输出 #2

4

C++实现

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5;
const int M=998244353;
long long n,dp[N][6];
int k,a[4];
int main(){
    cin>>n>>k;
    cin>>a[1]>>a[2]>>a[3]>>a[0];
    dp[0][k]=1;
    for(int i=1;i<=n;i++){
        if(a[i%4]==1){
            dp[i][1]=dp[i-1][0];
            dp[i][2]=dp[i-1][1];
            dp[i][3]=dp[i-1][2];
            dp[i][4]=dp[i-1][3];
            dp[i][5]=dp[i-1][4]+dp[i-1][5];
        }else if(a[i%4]==2){
            dp[i][0]=dp[i-1][1];
            dp[i][1]=dp[i-1][2]+dp[i-1][0];
            dp[i][2]=dp[i-1][3];
            dp[i][3]=dp[i-1][4];
            dp[i][4]=dp[i-1][5];
        }else if(a[i%4]==3){
            dp[i][0]=dp[i-1][1];
            dp[i][1]=dp[i-1][0]+dp[i-1][2];
            dp[i][2]=dp[i-1][1]+dp[i-1][3];
            dp[i][3]=dp[i-1][2]+dp[i-1][4];
            dp[i][4]=dp[i-1][3]+dp[i-1][5];
            dp[i][5]=dp[i-1][4]+dp[i-1][5];
        }
        dp[i][0]%=M,dp[i][1]%=M,dp[i][2]%=M,dp[i][3]%=M,dp[i][4]%=M,dp[i][5]%=M;
    }
    cout<<(dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3]+dp[n][4]+dp[n][5])%M;
    return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值