- 题意:
至今也没看懂题目叙述。。。弱菜,看别人程序看懂题意得。。。
给一串字符串,包含‘/’ ‘\’ ‘-’三种,分别表示下一个数比当前大,小,相等。要求出[a, b]区间内,满足要求的数有多少个:要求是,将字符串分成若干段,每段的符号均相同。再将数字也分成若干段,那么数字每一段与字符串的每一段对应,且数字段内相邻数的上升、下降、相等关系应满足对应字符串的符号关系,且每段数字段的数字个数应该大于等于对应符号段的符号个数。
- 分析:
数位DP解决时,状态为[pos][idx][pre],分别表示当前到数字串的第几位,对应的符号串的第几位,当前位的前一位数字是多少
注意前导零的处理即可
const int MAXN = 110; int dp[MAXN][MAXN][10]; char comp[MAXN], ipta[MAXN], iptb[MAXN]; char* bits; int len, lcp; bool check(int a, int b, char cp) { if (cp == '-') return a == b; else if (cp == '/') return a < b; else return a > b; } int dfs(int pos, int idx, int pre, bool lmt, bool fst) { if (pos == len) { return idx == lcp; } if (!lmt && !fst && ~dp[pos][idx][pre]) return dp[pos][idx][pre]; int e = 9, ret = 0; e = lmt ? bits[pos] - '0' : 9; FE(i, 0, e) { if (fst) ret += dfs(pos + 1, idx, i, lmt && i == e, fst && !i); else { if (idx < lcp && check(pre, i, comp[idx])) ret += dfs(pos + 1, idx + 1, i, lmt && i == e, 0); else if (idx > 0 && check(pre, i, comp[idx - 1])) ret += dfs(pos + 1, idx, i, lmt && i == e, 0); } ret %= MOD; } return lmt || fst ? ret : dp[pos][idx][pre] = ret; } int calc(char x[], bool sub) { CLR(dp, -1); len = strlen(x); int t = 0; while (x[t] == '0') t++; if (t >= len) return 0; if (sub) for (int i = len - 1; i >= t; i--) { if (x[i] != '0') { x[i]--; break; } else { x[i] = '9'; } } bits = x; return dfs(t, 0, 0, true, true); } int main() { while (~RS(comp)) { lcp = strlen(comp); scanf("%s%s", ipta, iptb); printf("%08d\n", ((calc(iptb, false) - calc(ipta, true)) % MOD + MOD) % MOD); } return 0; }
时间: 2024-10-11 21:25:14