[kuangbin带你飞]专题十五 数位DP K - Balanced Numbers (数位dp)(进制转换)

来源:互联网 发布:大学生网络借贷论文 编辑:程序博客网 时间:2024/04/29 13:55

这道题大意是当一个数每一位奇数的个数为偶数,每一位偶数的个数为奇数的时候,称这个数为 balanced number,所以对于 1~9 的数字,要保存三个状态:个数为0,个数为偶数,个数为奇数。这里就可以用3进制来保存,3^10大概不超过60000,所以用dp[20][60000]来保存状态;

下面见代码:

#include <cstdio>  #include <cstring>  #include <algorithm>using namespace std;#define LL long longint digit[25],w[15];LL dp[25][60005];int check(int sum) {  //检查是否符合条件,符合的+1int len = 0,d[15],flag = 1;while(sum) {d[++len] = sum%3;sum /= 3;}for(int i = 1;i <= len;i++) {if(i%2 == 1 && d[i] == 2) flag = 0;else if(i%2 == 0 && d[i] == 1) flag = 0;}return flag;}int add(int i,int sum) {  //把当前数字的个数存到sum里int dd = (sum/w[i]) % 3;if(dd == 0 || dd == 1) sum += w[i];else sum -= w[i];return sum; }LL dfs(int len,int sum,int fp) {if(!len) {//printf("%d\n",sum);if(check(sum)) return 1;else return 0;}if(!fp && dp[len][sum] != -1) return dp[len][sum];LL ans = 0;int maxfp = fp ? digit[len] : 9;for(int i = 0;i <= maxfp;i++) {if(!sum && !i) ans += dfs(len-1,0,fp && i == maxfp);else ans += dfs(len-1,add(i,sum),fp && i == maxfp);}if(!fp) dp[len][sum] = ans;return ans;}LL slove(LL x) {int len = 0;while(x) {digit[++len] = x%10;x /= 10;}return dfs(len,0,1);}int main() {int t;scanf("%d",&t);memset(dp,-1,sizeof(dp));w[0] = 1;for(int i = 1;i <= 10;i++) {w[i] = w[i-1]*3;}while(t--) {LL a,b;scanf("%lld%lld",&a,&b);  //输出是最坑的,wa了半天发现不支持%I64d,fuck,第一次见!printf("%lld\n",slove(b) - slove(a-1));}}

刷完数位dp专题,继续加油!

0 0