hdu 6156 Palindrome Function(数位dp)

xiaoxiao2021-02-28  103

之前做网络赛的时候,看出来这是数位dp了,奈何自己不会数位dp,网上找了个数位dp计算回文数的模板也套错了 因为不会数位dp,也找不出是哪里的毛病。 现在学了数位dp,再来切这题。 这题和LightOJ 1205 Palindromic Numbers基本一样,就是多了个不同的进制。在lightoj 1205的基础上,再加一维表示不同的进制,然后数位dp即可。做的时候数组开小了,wa了好几发。。查了老半天才发现。。

#include <stdio.h> #include <string.h> typedef long long LL; LL dp[40][40][40]; int digit[35]; int assist[35]; int calc(int num, int k) { int len = 0; while(num) { digit[len++] = num%k; num /= k; } return len; } LL dfs(int i, int len, int e, int k) { if(i == -1) return 1; if(!e && ~dp[k][len][i]) return dp[k][len][i]; LL res = 0; int u = e?digit[i]:(k-1); for(int d = 0; d <= u; ++d) { assist[i] = d; if(i == len && d == 0) res += dfs(i-1,len-1,e&&d==u,k); else if(i < (len+1)/2 && d == assist[len-i]) res += dfs(i-1,len,e&&d==u,k); else if(i >= (len+1)/2) res += dfs(i-1,len,e&&d==u,k); } return e?res:dp[k][len][i]=res; } LL solve(int num, int k) { int len = calc(num,k); return dfs(len-1,len-1,1,k); } int main() { int T,L,R,l,r,time = 0; memset(dp,-1,sizeof(dp)); scanf("%d",&T); while(T--) { scanf("%d %d %d %d",&L,&R,&l,&r); LL num = R-L+1; LL res = 0; LL cnt = 0; for(int i = l; i <= r; ++i) { cnt = solve(R,i)-solve(L-1,i); res = res + num-cnt + cnt*(LL)i; } printf("Case #%d: %I64d\n",++time,res); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-42977.html

最新回复(0)