由于数组长度为
n
n
n,那么我们可以知道在删除两个数到最后只有一个时,只需要
n
−
1
n - 1
n−1步,并且每一步都有两种选择。
问你在这
2
n
−
1
2^{n-1}
2n−1种情况中,最终剩下的值为
k
(
k
<
=
9
)
k(k <= 9)
k(k<=9)的情况每种有多少个。
思路分析
一开始,想试试
d
f
s
dfs
dfs,看了下数据范围,不太对劲,所以就想到了
d
p
dp
dp。
那么
d
p
dp
dp的状态转移方程怎么来找呢?
首先,我们可以肯定的是,无论是
F
F
F还是
G
G
G操作,最后插入到左侧时必然是一个小于
10
10
10的数。那么我们可以这样想,我们把上一个状态生成的数,用
d
p
dp
dp的一维来表示,这样的话,我们
f
o
r
for
for嵌套时,这一维只需要遍历
0
−
9
0-9
0−9即可。那么第一维呢,我的想法和官方题解一样,实际上就是直接用
d
p
dp
dp储存答案的个数,所以还有一维应该是现在是第几个数去操作。
即
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]指的是前面
i
i
i个数操作完能产生
j
j
j的个数。
所以
d
p
[
1
]
[
a
[
1
]
]
=
1
dp[1][a[1]] = 1
dp[1][a[1]]=1,并且状态转移方程可以这样理解:我们对第
i
+
1
i + 1
i+1个数操作时,先看一看前面一轮(即第
i
i
i轮)操作能产生的
0
−
9
0-9
0−9这些数的个数,然后再对该轮操作的答案更新即第二维变成
(
j
+
a
[
i
+
1
]
)
或
者
(
j
∗
a
[
i
+
1
]
)
(j + a[i + 1])或者(j * a[i + 1])
(j+a[i+1])或者(j∗a[i+1]),当然dp当前的值要加上
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]的值。
所以状态转移方程应该是这两个:
d
p
[
i
+
1
]
[
(
j
+
a
[
i
+
1
]
)
m
o
d
10
]
=
(
d
p
[
i
]
[
j
]
+
d
p
[
i
+
1
]
[
(
j
+
a
[
i
+
1
]
)
]
)
,
d
p
第
二
维
和
答
案
要
取
模
,
这
里
用
不
了
百
分
号
dp[i + 1][(j + a[i + 1]) mod10] = (dp[i][j] + dp[i + 1][(j + a[i + 1])]),dp第二维和答案要取模,这里用不了百分号
dp[i+1][(j+a[i+1])mod10]=(dp[i][j]+dp[i+1][(j+a[i+1])]),dp第二维和答案要取模,这里用不了百分号
d
p
[
i
+
1
]
[
(
j
∗
a
[
i
+
1
]
)
m
o
d
10
]
=
(
d
p
[
i
]
[
j
]
+
d
p
[
i
+
1
]
[
(
j
∗
a
[
i
+
1
]
)
]
)
,
d
p
第
二
维
和
答
案
要
取
模
,
这
里
用
不
了
百
分
号
dp[i + 1][(j * a[i + 1]) mod10] = (dp[i][j] + dp[i + 1][(j * a[i + 1])]),dp第二维和答案要取模,这里用不了百分号
dp[i+1][(j∗a[i+1])mod10]=(dp[i][j]+dp[i+1][(j∗a[i+1])]),dp第二维和答案要取模,这里用不了百分号
因此答案就是
d
p
[
n
]
[
k
]
(
k
<
=
10
)
dp[n][k](k <= 10)
dp[n][k](k<=10)
感觉写的不是很清楚,如果觉得哪里读的不顺口,请告诉我一下。
代码如下
#include<bits/stdc++.h>#definelllonglongusingnamespace std;constint maxn =1e5+10;constint mod =998244353;int dp[maxn +1][10];int a[maxn];intmain(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);int n;
cin >> n;for(int i =1; i <= n; i++){
cin >> a[i];}memset(dp,0,sizeof(dp));
dp[1][a[1]]=1;for(int i =1; i <= n -1; i++){for(int j =0; j <=9; j++){
dp[i +1][(j + a[i +1])%10]=(dp[i][j]+ dp[i +1][(j + a[i +1])%10])% mod;
dp[i +1][(j * a[i +1])%10]=(dp[i][j]+ dp[i +1][(j * a[i +1])%10])% mod;}}for(int k =0; k <10; k++)
cout << dp[n][k]% mod << endl;return0;}