ABC220 D - FG operation(dp)

目录

Description

\(n\) 个数,有两种操作

1.删除前面两个数,然后在前面插入这两个数的和

2.删除前面两个数,然后在前面插入这两个数的积

最后会剩下一个数,问 \(0\ 1\ ...\ 9\) 出现次数各是多少

State

\(2<=n<=10^5\)

\(0<=a[i]<=9\)

Input

5
0 1 2 3 4

Output

6
0
1
1
4
0
1
1
0
2

Solution

很典型的记忆化搜索

\[01234 \\ 1234\qquad \quad 0234 \\ 334\qquad 234\qquad 234\qquad 034\\ 64\quad 94\quad 54\quad 64 \quad 54\quad 64\quad 34\quad 04\\ 0\quad 4\quad 3\quad 6\quad 9\quad 0\quad 0\quad 4 \quad 9\quad 0\quad 0\quad 4\quad 7\quad 2 \quad 4\quad 0\\ \]

发现会有很多重复的序列,将序列转成字符串,然后记忆化搜索?

一个序列的最终答案,只与前两个数有关,所以只要记录前两个数就可以了,这样 \(dp\) 也就可以解决这个问题了

$dp[i][j]: $ 表示第 \(i\) 个数为第 \(1\) 个数的时候,答案为 \(j\) 的个数


Code

const int N = 1e6 + 5;

    int n, m, _, k;
    int a[N];
    ll dp[N][10];

signed main()
{
    //IOS;
    while(~ sd(n)){
        rep(i, 1, n) sd(a[i]);
        dp[1][a[1]] = 1;
        for(int i = 2; i <= n; i ++){
            for(int j = 0; j <= 9; j ++){
                dp[i][(a[i] + j) % 10] += dp[i - 1][j];
                dp[i][(a[i] * j) % 10] += dp[i - 1][j];
                dp[i][(a[i] + j) % 10] %= mod;
                dp[i][(a[i] * j) % 10] %= mod;
            }
        }
        rep(i, 0, 9)
            pll(dp[n][i]);
    }
    //PAUSE;
    return 0;
}
posted @ 2021-09-28 14:19  Bcoi  阅读(254)  评论(0)    收藏  举报