首页 > 代码库 > [LightOJ1205]Palindromic Numbers(数位dp)
[LightOJ1205]Palindromic Numbers(数位dp)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1205
题意:求[l,r]内回文数的数量。
dp(s,l,ok)表示数字以s为开头,长度为l的时是/不是回文数
dp(s,l,ok)可以由dp(s,l-1,ok)更新来,当且仅当接下来插入的一位与s对应的位置相同。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int maxn = 22; 6 int digit[maxn], rev[maxn]; 7 LL dp[maxn][maxn][2]; 8 LL l, r; 9 10 LL dfs(int s, int l, bool ok, bool flag) {11 if(l < 0) return ok;12 if(!flag && ~dp[s][l][ok]) return dp[s][l][ok];13 int pos = flag ? digit[l] : 9;14 LL ret = 0;15 for(int i = 0; i <= pos; i++) {16 rev[l] = i;17 if(i == 0 && s == l) ret += dfs(s-1, l-1, ok, flag&&(i==pos));18 else if(ok && l < (s + 1) / 2) ret += dfs(s, l-1, i==rev[s-l], flag&&(i==pos));19 else ret += dfs(s, l-1, ok, flag&&(i==pos));20 }21 if(!flag) dp[s][l][ok] = ret;22 return ret;23 }24 25 LL f(LL x) {26 int pos = 0;27 while(x) {28 digit[pos++] = x % 10;29 x /= 10;30 }31 return dfs(pos-1, pos-1, true, true);32 }33 34 int main() {35 //freopen("in", "r", stdin);36 int T, _ = 1;37 scanf("%d", &T);38 memset(dp, -1, sizeof(dp));39 while(T--) {40 scanf("%lld%lld",&l,&r);41 if(l > r) swap(l, r);42 printf("Case %d: %lld\n", _++, f(r) - f(l-1));43 }44 return 0;45 }
[LightOJ1205]Palindromic Numbers(数位dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。