Ah, how I long to embrace
不要尝试在赛时获得图灵奖。
模拟赛 T2,被创死了。
赛时一直想着有向图怎么进行拓扑序计数,结果发现完全没有办法计数。
这题 \(O(n^3)\) 的策略是显然的,不再赘述。
但是我们不难发现 \(O(n^3)\) 的区间DP是没有优化的机会的,因此只能开动脑筋了。考虑观察题目,结果发现运算符的后面一定会有 (,因此不妨转化成括号序列匹配,每一次的运算符会添加 (,每一次的数字可以添加任意数量的 ),后缀和优化一下就做完了。时间复杂度 \(O(n^2)\)。
Code
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define File(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define LL long long
#define fi first
#define se second
const LL mod = 1e6 + 3;
const int N = 2e3 + 10;
LL f[N][N];
string s;
int n;
char c[N];
int main(){
IOS;
cin >> s;
int lens = s.size();
for(int i=0;i<lens;i++){
if(s[i] >= '0' && s[i] <= '9'){
c[++n] = 'n';
while(i < lens && s[i] >= '0' && s[i] <= '9') i ++ ;
i -- ;
}
else{
c[++n] = s[i];
}
}
for(int i=1;i<=n;i++)
if(c[i-1] != 'n' && (c[i] == '*' || c[i] == '/')){
cout << 0;
return 0;
}
if(c[n] != 'n'){
cout << 0;
return 0;
}
f[0][0] = 1;
for(int i=1;i<=n;i++){
if(c[i] != 'n'){
for(int j=1;j<=n;j++)
f[i][j] = f[i-1][j-1];
}
else{
for(int j=n;j>=0;j--)
f[i][j] = (f[i][j+1] + f[i-1][j]) % mod;
}
}
cout << f[n][0];
return 0;
}

浙公网安备 33010602011771号