题目链接
题目大意:给定
N
N
N个字符串
S
1
,
…
,
S
n
S_1 ,…,S_n
S1,…,Sn ,每个字符串内容为
A
N
D
AND
AND 或
O
R
OR
OR 。找到使
y
n
y_n
yn为
1
1
1的序列
(
x
0
,
…
,
x
n
)
(x_0 ,…,x_n)
(x0,…,xn)的数量。
1.
y
0
=
x
0
y_0 = x_0
y0=x0
2.对于
i
≥
1
i ≥ 1
i≥1 ,当
S
i
Si
Si 为
A
N
D
AND
AND时,
y
i
=
y
i
−
1
∧
x
i
y_i =y _{i-1} ∧x_i
yi=yi−1∧xi ;当
S
i
Si
Si 为
O
R
OR
OR时,
y
i
=
y
i
−
1
∨
x
i
y_i =y _{i-1} ∨x_i
yi=yi−1∨xi
思路:
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示前i步,y为j的方案数,初始状态为
f
[
0
]
[
0
]
=
f
[
0
]
[
1
]
=
1
f[0][0]=f[0][1]=1
f[0][0]=f[0][1]=1,
然后枚举下一步x的选择进行dp的转移方案数,
f
[
n
]
[
1
]
f[n][1]
f[n][1]即是所要求的答案。
代码:
#include <iostream>
#include <cstdio>
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair <int, int> PII;
const int N = 1e5 + 10;
const ll mod = 1e9 + 7;
int t, n, a[N];
string s[80];
ll f[80][2];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i];
f[0][0] = 1;
f[0][1] = 1;
for(int i = 1; i <= n; i++) {
if(s[i] == "OR") {
f[i][0] = f[i - 1][0];
f[i][1] = 2 * f[i - 1][1] + f[i - 1][0];
}
else {
f[i][0] = f[i - 1][1] + 2 * f[i - 1][0];
f[i][1] = f[i - 1][1];
}
}
printf("%lld", f[n][1]);
return 0;
}