zoukankan      html  css  js  c++  java
  • spoj 10606 Balanced Numbers 数位dp

    题目链接

    一个数称为平衡数, 满足他各个数位里面的数, 奇数出现偶数次, 偶数出现奇数次, 求一个范围内的平衡数个数。

    用三进制压缩, 一个数没有出现用0表示, 出现奇数次用1表示, 出现偶数次用2表示, 这样只需要开一个20*60000的数组。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define pb(x) push_back(x)
     4 #define ll long long
     5 #define mk(x, y) make_pair(x, y)
     6 #define lson l, m, rt<<1
     7 #define mem(a) memset(a, 0, sizeof(a))
     8 #define rson m+1, r, rt<<1|1
     9 #define mem1(a) memset(a, -1, sizeof(a))
    10 #define mem2(a) memset(a, 0x3f, sizeof(a))
    11 #define rep(i, a, n) for(int i = a; i<n; i++)
    12 #define ull unsigned long long
    13 typedef pair<int, int> pll;
    14 const double PI = acos(-1.0);
    15 const double eps = 1e-8;
    16 const int mod = 1e9+7;
    17 const int inf = 1061109567;
    18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    19 int digit[20], a[20];
    20 ll dp[20][60000];
    21 int judge(int num) {
    22     int cnt = 0;
    23     for(int i = 0; i<10; i++) {
    24         a[i] = num%3;
    25         num/=3;
    26     }
    27     for(int i = 0; i<10; i++) {
    28         if(i%2==0&&a[i]==2)
    29             return 0;
    30         if(i%2==1&&a[i]==1)
    31             return 0;
    32     }
    33     return 1;
    34 }
    35 int cal(int num, int tmp) {
    36     int cnt = 0;
    37     for(int i = 0; i<10; i++) {
    38         a[i] = num%3;
    39         num/=3;
    40     }
    41     a[tmp]++;
    42     if(a[tmp]==3)
    43         a[tmp]=1;
    44     for(int i = 9; i>=0; i--) {
    45         num = num*3+a[i];
    46     }
    47     return num;
    48 }
    49 ll dfs(int len, int num, int fp, bool first) {
    50     if(!len) {
    51         return judge(num);
    52     }
    53     if(!fp&&dp[len][num]!=-1) {
    54         return dp[len][num];
    55     }
    56     ll ret = 0;
    57     int maxx = fp?digit[len]:9;
    58     for (int i = 0; i<=maxx; i++) {
    59         ret += dfs(len-1, (first&&i==0)?0:cal(num, i), fp&&i==maxx, i==0&&first);
    60     }
    61     if(!fp)
    62         return dp[len][num] = ret;
    63     return ret;
    64 }
    65 ll cal(ll n) {
    66     int len = 0;
    67     while(n) {
    68         digit[++len] = n%10;
    69         n/=10;
    70     }
    71     return dfs(len, 0, 1, true);
    72 }
    73 int main()
    74 {
    75     mem1(dp);
    76     int t;
    77     ll a, b;
    78     cin>>t;
    79     while(t--) {
    80         scanf("%lld%lld", &a, &b);    //I64d会超时......
    81         printf("%lld
    ", cal(b)-cal(a-1));
    82     }
    83 }
  • 相关阅读:
    指针与数组名
    c语言指针函数与函数指针
    c语言结构体
    c语言
    c语言全局变量
    c语言函数传递数组
    c实例_挑战程序竞赛,蚂蚁
    c语言字符串实例
    安又琪-唱得响亮
    乡村爱情
  • 原文地址:https://www.cnblogs.com/yohaha/p/5040809.html
Copyright © 2011-2022 走看看