题解 CF1766E 【Decomposition】
首先,
现在,我们可以发现:扔掉
- 如果有
3 ,一定在第一个序列里。 - 可能存在暂时扔不进第一个序列的
1, 2 ,至多会再构成两个序列。
考虑 dp。设
每次遇到一个
答案:
时间复杂度为
代码:
#include <stdio.h>
typedef long long ll;
int dp[7][7][7][7];
int main(){
int n, cur = 0;
ll ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
int a;
scanf("%d", &a);
dp[cur][0][0][0]++;
if (a == 0){
ans += (ll)i * (n - i + 1);
} else {
int nxt = cur ^ 1;
for (int j = 0; j <= 3; j++){
for (int k = 0; k <= 3; k++){
for (int l = 0; l <= 3; l++){
dp[nxt][j][k][l] = 0;
}
}
}
for (int j = 0; j <= 3; j++){
for (int k = 0; k <= 3; k++){
for (int l = 0; l <= 3; l++){
if (j == 0 || (j & a)){
dp[nxt][a][k][l] += dp[cur][j][k][l];
} else if (k == 0 || (k & a)){
dp[nxt][j][a][l] += dp[cur][j][k][l];
} else {
dp[nxt][j][k][a] += dp[cur][j][k][l];
}
}
}
}
cur = nxt;
}
for (int j = 0; j <= 3; j++){
for (int k = 0; k <= 3; k++){
for (int l = 0; l <= 3; l++){
ans += dp[cur][j][k][l] * ((j > 0 ? 1 : 0) + (k > 0 ? 1 : 0) + (l > 0 ? 1 : 0));
}
}
}
}
printf("%lld", ans);
return 0;
}