来源:杭州发电大学联赛(1)I 题。
对于一个十进制非负整数 n,我们可以按照从高位到低位将其写成一个由数位 0∼9 构成的字符串 S(n)(不含前导 0)。
称一个仅由 < 和 > 组成的串为关系串。对于一个长度为 k 的关系串 S=s1s2…sk+1,如果任意 1≤i≤k,都有关系 ??(??,??+1)成立,则称字符串 S 满足关系串 R 的限制。
其中关系 ri(si,si+1) 成立只有两种情况,r=< 且 si<si+1 或者 r=> 且 si>si+1 比较按照字典序顺序。
现在定义 f(n,R) 表示 S(n) 中有多少个子序列满足关系串 R 的限制。给定 l,r,R,求:
其中一个字符串的子序列定义为从原字符串中删去若干个(可以不删或删空)字符得到的新字符串。
本题单个测试点内包含多组测试数据。
第一行一个整数 ?(1≤?≤10),表示数据组数。
对于每组数据,第一行两个整数 (1≤?≤?<10500),意义如题。
第二行一个关系串 ?(1≤∣R∣≤500),意义如题。
输入:
5
12435 12435
<<
114514 114514
<><
1919810 1919810
<><>
1234 4321
<>
114514 1919810
<>>
输出
7
5
5
4628
4377883
错误代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, m, k, dp[506][506][10][2][2][2];
char l[506], r[506], R[506];
const int p = 998244353;
int dfs(int i, int ri, int lst, int limited, int unlim, int zero) {
if (i == n + 1) return 1;
if (dp[i][ri][lst][limited][unlim][zero] != -1) return dp[i][ri][lst][limited][unlim][zero];
int ans = 0;//dfs(i + 1, ri, lst, limited, unlim, zero);
//cout << lst << " " << ri << " " << i << " " << " " << limited << " " << unlim << "\n";
if (ri == 0) {
assert(!zero);
for (int dig = (unlim ? 0ll : l[i] - 48); dig <= (limited ? 9 : (int)(r[i] - '0')); ++dig) {
ans += dfs(i + 1, ri + (zero || (dig != 0)), dig, (limited || (dig != r[i] - '0')), (unlim || (dig != l[i] - '0')), zero || (dig != 0));
}
} else if (ri <= k && R[ri] == '>') {
assert(zero);
for (int dig = (unlim ? 0ll : l[i] - 48); dig <= min({lst - 1, (limited ? 9 : (int)(r[i] - '0'))}); ++dig) {
ans += dfs(i + 1, ri + 1, dig, (limited || (dig != r[i] - 48)), (unlim || (dig != l[i] - '0')),1);
}
} else if (ri <= k && R[ri] == '<') {
assert(zero);
for (int dig = max((unlim ? 0ll : l[i] - 48), lst + 1); dig <= (limited ? 9 : (int)(r[i] - '0')); ++dig) {
ans += dfs(i + 1, ri + 1, dig, (limited || (dig != r[i] - 48)), (unlim || (dig != l[i] - '0')),1);
}
}
for (int dig = (unlim ? 0ll : l[i] - 48); dig <= (limited ? 9 : (int)(r[i] - '0')); ++dig) {
ans += dfs(i + 1, ri, lst, (limited || (dig != r[i] - 48)), (unlim || (dig != l[i] - '0')), zero);
}
return dp[i][ri][lst][limited][unlim][zero] = ans % p;
}
void solve() {
cin >> (l + 1) >> (r + 1) >> (R + 1);
n = strlen(l + 1);
m = strlen(r + 1);
for (int j = m; j >= (m - n + 1); --j) l[j] = l[j - (m - n)];
for (int j = 1; j <= m - n; ++j) l[j] = '0';
k = strlen(R + 1);
memset(dp, 255, sizeof(dp));
int tmp = dfs(1, 0, 0, 0, 0, 0);
cout << tmp << "\n";
}
signed main() {
//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int tc; cin >> tc;
while (tc--) solve();
}
蒟蒻要求不高,只求调过样例,我会不会是题意理解错了。