【HDOJ】3386 Final Kichiku “Lanlanshu”
数位DP。
需要注意的是需要特殊处理前导0,另外连续的==匹配,不要计重了,尽量贪心的匹配掉。
1 /* 3886 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 const int mod = 100000000; 45 const int maxl = 105; 46 const int maxn = 105; 47 char ps[maxl], ps_[maxl]; 48 char sa[maxl], sb[maxl]; 49 int a[maxl], plen; 50 int dp[maxl][maxn][2][10]; 51 bool dp_[maxl][maxn]; 52 53 void f(char *s, int& l) { 54 int len = strlen(s); 55 int i = 0; 56 57 l = 0; 58 while (i<len-1 && s[i]=='0') 59 ++i; 60 while (i < len) { 61 s[l++] = s[i++]-'0'; 62 } 63 s[l] = '\0'; 64 } 65 66 bool check(char ch, int d, int dd) { 67 if (ch == '/') 68 return d < dd; 69 if (ch == '-') 70 return d == dd; 71 if (ch == '\\') 72 return d > dd; 73 return false; 74 } 75 76 bool judge(char *s, int len) { 77 if (len==1 || check(ps[1], s[0], s[1])==false) 78 return false; 79 80 memset(dp_, false, sizeof(dp_)); 81 dp_[1][1] = true; 82 83 rep(j, 1, plen) { 84 rep(i, 1, len-1) { 85 if (!dp_[j][i]) 86 continue; 87 88 if (check(ps[j], s[i], s[i+1])) 89 dp_[j][i+1] = true; 90 if (check(ps[j+1], s[i], s[i+1])) 91 dp_[j+1][i+1] = true; 92 } 93 } 94 95 return dp_[plen][len-1]; 96 } 97 98 int cal(char *s, int len) { 99 if (len <= 1) 100 return 0; 101 102 memset(dp, -1, sizeof(dp)); 103 rep(k, 0, s[0]) { 104 rep(kk, 0, 10) { 105 if (k == 0) { 106 if (dp[0][1][0][kk] == -1) 107 dp[0][1][0][kk] = 1; 108 else 109 ++dp[0][1][0][kk]; 110 continue; 111 } 112 113 if (check(ps[1], k, kk)) { 114 if (dp[1][1][0][kk] == -1) 115 dp[1][1][0][kk] = 1; 116 else 117 ++dp[1][1][0][kk]; 118 } 119 } 120 } 121 rep(kk, 0, s[1]+1) { 122 int at = kk==s[1]; 123 if (check(ps[1], s[0], kk)) { 124 if (dp[1][1][at][kk] == -1) 125 dp[1][1][at][kk] = 1; 126 else 127 ++dp[1][1][at][kk]; 128 } 129 } 130 131 rep(i, 0, plen+1) { 132 int ii = i + 1; 133 rep(j, 1, len-1) { 134 int jj = j + 1; 135 136 // consider boundary 137 if (dp[i][j][1][s[j]] >= 0) { 138 rep(k, 0, s[j+1]+1) { 139 int at = k==s[j+1]; 140 141 if (check(ps[ii], s[j], k)) { 142 if (dp[ii][jj][at][k] >= 0) { 143 dp[ii][jj][at][k] = (dp[ii][jj][at][k] + dp[i][j][1][s[j]]) % mod; 144 } else { 145 dp[ii][jj][at][k] = dp[i][j][1][s[j]]; 146 } 147 } else if (check(ps[i], s[j], k)) { 148 if (dp[i][jj][at][k] >= 0) { 149 dp[i][jj][at][k] = (dp[i][jj][at][k] + dp[i][j][1][s[j]]) % mod; 150 } else { 151 dp[i][jj][at][k] = dp[i][j][1][s[j]]; 152 } 153 } 154 } 155 } 156 157 // consider < boundary 158 rep(k, 0, 10) { 159 if (dp[i][j][0][k] < 0) 160 continue; 161 rep(kk, 0, 10) { 162 if (i == 0) { 163 if (k == 0) { 164 if (dp[i][jj][0][kk] >= 0) { 165 dp[i][jj][0][kk] = (dp[i][jj][0][kk] + dp[i][j][0][k]) % mod; 166 } else { 167 dp[i][jj][0][kk] = dp[i][j][0][k]; 168 } 169 } else { 170 if (check(ps[ii], k, kk)) { 171 if (dp[ii][jj][0][kk] >= 0) { 172 dp[ii][jj][0][kk] = (dp[ii][jj][0][kk] + dp[i][j][0][k]) % mod; 173 } else { 174 dp[ii][jj][0][kk] = dp[i][j][0][k]; 175 } 176 } 177 } 178 continue; 179 } 180 181 if (check(ps[ii], k, kk)) { 182 if (dp[ii][jj][0][kk] >= 0) { 183 dp[ii][jj][0][kk] = (dp[ii][jj][0][kk] + dp[i][j][0][k]) % mod; 184 } else { 185 dp[ii][jj][0][kk] = dp[i][j][0][k]; 186 } 187 } else if (check(ps[i], k, kk)) { 188 if (dp[i][jj][0][kk] >= 0) { 189 dp[i][jj][0][kk] = (dp[i][jj][0][kk] + dp[i][j][0][k]) % mod; 190 } else { 191 dp[i][jj][0][kk] = dp[i][j][0][k]; 192 } 193 } 194 } 195 } 196 } 197 } 198 199 int ret = 0; 200 201 rep(k, 0, 10) { 202 if (dp[plen][len-1][1][k] >= 0) 203 ret = (ret + dp[plen][len-1][1][k]) % mod; 204 if (dp[plen][len-1][0][k] >= 0) 205 ret = (ret + dp[plen][len-1][0][k]) % mod; 206 } 207 208 return ret; 209 } 210 211 void solve() { 212 int alen, blen; 213 int ans = 0, tmp; 214 215 plen = strlen(ps+1); 216 f(sa, alen); 217 f(sb, blen); 218 219 tmp = cal(sb, blen); 220 ans += tmp; 221 tmp = cal(sa, alen); 222 ans -= tmp; 223 if (judge(sa, alen)) 224 ++ans; 225 226 ans = (ans + mod) % mod; 227 printf("%08d\n", ans); 228 } 229 230 int main() { 231 ios::sync_with_stdio(false); 232 #ifndef ONLINE_JUDGE 233 freopen("data.in", "r", stdin); 234 freopen("data.out", "w", stdout); 235 #endif 236 237 while (scanf("%s", ps+1)!=EOF) { 238 scanf("%s %s", sa, sb); 239 solve(); 240 } 241 242 #ifndef ONLINE_JUDGE 243 printf("time = %d.\n", (int)clock()); 244 #endif 245 246 return 0; 247 }