• HDU 4734 F(x)


    题意:对于一个数x,将其表示成十进制为(An,An-1...A2,A1),则F(x) = An*2^(n-1) + A(n-1)*2^(n-2) + ... + A2*2 + A1。给定整数a,b,求F()值不超过F(a)且属于[0,b]的整数有多少个。a,b < 10^9,10000组case。

    Ps:这是2013年成都区域赛网络赛的题目。

    解法:设数组d[i][j]表示长度为i的数(首位可以为0)中F()值不超过j的数有多少个。具体解法见代码。

    tag:数位DP

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-12-14 15:50
     4  * File Name: DP-HDU-4734.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 
    10 using namespace std;
    11 
    12 #define CLR1(x) memset(x, -1, sizeof(x))
    13 #define CLR(x) memset(x, 0, sizeof(x))
    14 
    15 int dit_b[20], d[20][10000];
    16 
    17 int Mypow(int p, int n)
    18 {
    19     int ret = 1;
    20     while (n){
    21         if (n & 1) ret *= p;
    22         n >>= 1;
    23         p *= p;
    24     }
    25     return ret;
    26 }
    27 
    28 int dit_dev(int x, int* dit)
    29 {
    30     int ret = 0;
    31     while (x){
    32         dit[ret++] = x % 10;
    33         x /= 10;
    34     }
    35     return ret;
    36 }
    37 
    38 int cal(int x)
    39 {
    40     int ret = 0, dit[20];
    41     CLR (dit);
    42     int len = dit_dev(x, dit);
    43     for (int i = 0; i < len; ++ i)
    44         ret += dit[i] * Mypow(2, i);
    45     return ret;
    46 }
    47 
    48 int rec(int len, int cost, bool flag)
    49 {
    50     if (len < 0) return 1;
    51 
    52     if (flag){
    53         int &ret = d[len][cost];
    54         if (ret != -1) return ret;
    55         ret = 0;
    56 
    57         for (int i = 0; i < 10; ++ i){
    58             int tmp = i * Mypow(2, len);
    59             if (tmp <= cost) ret += rec(len-1, cost-tmp, 1);
    60         }
    61         return ret;
    62     }
    63     else{
    64         int ret = 0;
    65         for (int i = 0; i < dit_b[len]; ++ i){
    66             int tmp = i * Mypow(2, len);
    67             if (tmp <= cost) ret += rec(len-1, cost-tmp, 1);
    68         }
    69         int tmp = dit_b[len] * Mypow(2, len);
    70         if (tmp <= cost) ret += rec(len-1, cost-tmp, 0);
    71         return ret;
    72     }
    73 }
    74 
    75 int main()
    76 {
    77     int a, b, T, test = 0;
    78     CLR1 (d);
    79     scanf ("%d", &T);
    80     while (T--){
    81         scanf ("%d%d", &a, &b);
    82         CLR (dit_b);
    83         int tmp = cal(a), len_b = dit_dev(b, dit_b);
    84         printf ("Case #%d: %d
    ", ++test, rec(len_b-1, tmp, 0));
    85     }
    86     return 0;
    87 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    Linux文件与文件系统的压缩
    Linux命令与文件查找
    js兼容pc和移动端的简单拖拽效果
    图片懒加载插件
    css小特效
    创建对象和方法
    距离2021年春节还剩。。。
    固定尺寸的图片焦点图案例
    数据库操作
    简单sql操作
  • 原文地址:https://www.cnblogs.com/plumrain/p/HDU_4734.html
Copyright © 2020-2023  润新知