FG操作

解题思路

这道题目要求我们计算在给定的数字序列上,通过一系列F(加法取模)和G(乘法取模)操作,最终得到0到9中每个数字的可能操作方式的数量。由于操作顺序的不同会导致不同的结果,我们需要动态规划来高效地统计所有可能的操作路径。

  1. 问题分析

    • 每次操作都是对当前序列的最左端两个数字进行操作,并将结果放回左端,直到序列长度为1。
    • 每一步操作有两种选择:F(加法取模)或G(乘法取模)。
    • 我们需要统计所有可能的操作路径,最终得到0到9每个数字的出现次数。
  2. 动态规划

    • 使用动态数组prev_dp来记录当前数字可能的值及其对应的路径数。
    • 初始时,prev_dp中只有第一个数字的位置为1(因为初始序列只有第一个数字)。
    • 对于后续的每个数字,我们根据当前可能的数字值(即prev_dp中的非零项),分别计算F和G操作后的新数字,并更新到curr_dp中。
    • 每次处理完一个数字后,将curr_dp复制到prev_dp,以便处理下一个数字。
  3. 复杂度分析

    • 时间复杂度:O(N * 10),其中N是数字序列的长度。对于每个数字,我们最多处理10种可能的当前数字值。
    • 空间复杂度:O(1),只使用了固定大小的数组(10个元素)来存储中间结果。

代码注释

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl "\n"
const int INF = 0x7fffffff;
const int mod = 998244353;
const int N = 1e5+5; 

int n;
int a[N];
int prev_dp[10]; // 前一个状态的动态规划数组,记录当前可能的值及其路径数
int curr_dp[10]; // 当前状态的动态规划数组,用于临时存储更新后的值

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i]; // 输入数字序列
    
    // 初始化prev_dp,初始状态下只有第一个数字a[1]的路径数为1
    memset(prev_dp, 0, sizeof(prev_dp));
    prev_dp[a[1]] = 1;
    
    for(int i = 2; i <= n; i++) { // 从第二个数字开始处理
        memset(curr_dp, 0, sizeof(curr_dp)); // 清空当前状态的数组
        for(int j = 0; j <= 9; j++) { // 遍历0到9的所有可能当前值
            if(prev_dp[j] == 0) continue; // 如果当前值j的路径数为0,跳过
            int f = (j + a[i]) % 10; // 计算F操作后的新值
            int g = (j * a[i]) % 10; // 计算G操作后的新值
            // 更新curr_dp中的路径数,取模防止溢出
            curr_dp[f] = (curr_dp[f] + prev_dp[j]) % mod;
            curr_dp[g] = (curr_dp[g] + prev_dp[j]) % mod;
        }
        // 将curr_dp的值复制到prev_dp,准备处理下一个数字
        memcpy(prev_dp, curr_dp, sizeof(curr_dp));
    }
    
    // 输出最终结果,即prev_dp中0到9的路径数
    for(int i = 0; i <= 9; i++) {
        cout << prev_dp[i] << endl;
    }
    return 0;
}

代码解释

  1. 输入处理:读取数字序列的长度n和序列a
  2. 初始化prev_dp数组初始时只有a[1]的位置为1,表示初始状态下只有第一个数字的路径数为1。
  3. 动态规划处理
    • 对于每个数字a[i],清空curr_dp数组。
    • 遍历prev_dp中的每个可能值j,计算F和G操作后的新值fg,并更新curr_dp中的路径数。
    • curr_dp的值复制到prev_dp,以便处理下一个数字。
  4. 输出结果:最终prev_dp中的值即为0到9每个数字的路径数,按顺序输出。

这种方法高效地利用了动态规划来避免重复计算,确保了在O(N)时间内解决问题。

posted @ 2025-05-13 20:05  季风起  阅读(4)  评论(0)    收藏  举报