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;
}

浙公网安备 33010602011771号