首页 > 代码库 > HDU 3886 Final Kichiku “Lanlanshu” 数位DP
HDU 3886 Final Kichiku “Lanlanshu” 数位DP
给你一个字符串/表示当前位比前一位小-表示和前一位相等\ 表示比前一位大 求a到b之间有多少个数满足方案
dp[i][j][k] 到第i位满足字符串的第j位前一位是k的方案数
#include <cstdio>#include <cstring>using namespace std;const int maxn = 110;char s[maxn], A[maxn], B[maxn];int a[maxn];int dp[maxn][maxn][10];int m;bool ok(int i, int j, char c){ if(c == '/') return i < j; if(c == '-') return i == j; if(c == '\\') return i > j;}int dfs(int x, int l, int p, int first, int flag){ if(x == -1) return l == m; if(!flag && dp[x][l][p] != -1) return dp[x][l][p]; int end; if(flag) end = a[x]; else end = 9; int ans = 0; for(int i = 0; i <= end; i++) { if(first) { ans += dfs(x-1, l, i, first&&i==0, flag&&i == end); ans %= 100000000; } else if(l < m && ok(p, i, s[l])) { ans += dfs(x-1, l+1, i, first&&i==0, flag&&i == end); ans %= 100000000; } else if(l > 0 && ok(p, i, s[l-1])) { ans += dfs(x-1, l, i, first&&i==0, flag&&i == end); ans %= 100000000; } } if(!flag) dp[x][l][p] = ans; return ans;}int cal(char* s, int flag){ int len = 0, n = strlen(s); int j = 0; while(s[j] == '0') j++; for(int i = n-1; i >= j; i--) a[len++] = s[i] - '0'; if(flag) { for(int i = 0; i < len; i++) { if(a[i]) { a[i]--; break; } else a[i] = 9; } } return dfs(len-1, 0, 0, 1, 1);}int main(){ while(scanf("%s", s) != EOF) { memset(dp, -1, sizeof(dp)); m = strlen(s); scanf("%s %s", A, B); printf("%08d\n", (cal(B, 0)-cal(A, 1)+100000000)%100000000); } return 0;}
HDU 3886 Final Kichiku “Lanlanshu” 数位DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。