zoukankan      html  css  js  c++  java
  • hdu 4734 F(x)

    题意:

    对一个数x(A nn-1n-2 ... A 21),定义它的权重为F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... + A 2 * 2 + A 1 * 1。

    现在给出A和B,要求计算出0到B的比区间内有多少个数字的权重不超过A的权重。

    思路:

    数位dp。

    一开始定义dp[pos][sum]表示处理到第pos位,前缀和为sum的数字的个数,每次输入都需要清空dp数组,所以tle了。

    其实这个dp的状态是与输入的A有关系的,但是数位dp的本质是与输入的具体数字无关,只与数字的某些状态和特征有关。

    所以改变一下dp的状态,用dp[pos][sum]表示从第0位到第pos位小于等于sum的数字有多少,这样就与输入的数字没有关系了。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 int p[15];
     6 int dp[15][1<<13];
     7 int c[15];
     8 int ans;
     9 int cal(int x)
    10 {
    11     int cnt = 0;
    12     int res = 0;
    13     while (x)
    14     {
    15         res += (x % 10) * p[cnt];
    16         x /= 10;
    17         cnt++;
    18     }
    19     return res;
    20 }
    21 int dfs(int pos,int lim,int sta)
    22 {
    23     if (sta < 0) return 0;
    24     if (pos == -1) return 1; 
    25     int mx = lim ? c[pos] : 9;
    26     if (!lim && dp[pos][sta] != -1) return dp[pos][sta];
    27     int res = 0;
    28     for (int i = 0;i <= mx;i++)
    29     {
    30         int cur = sta - i * p[pos];
    31         //printf("pos = %d,cur = %d
    ",pos,cur);
    32         //if (cur > ans) continue;
    33         res += dfs(pos-1,lim && i == mx,cur);
    34     }
    35     if (!lim) return dp[pos][sta] = res;
    36     return res;
    37 }
    38 int solve(int x)
    39 {
    40     int cnt = 0;
    41     while (x)
    42     {
    43         c[cnt++] = x % 10;
    44         x /= 10;
    45     }
    46     int res = dfs(cnt-1,1,ans);
    47     return res;
    48 }
    49 int main()
    50 {
    51     p[0] = 1;
    52     for (int i = 1;i < 15;i++) p[i] = 2 * p[i-1];
    53     int t;
    54     scanf("%d",&t);
    55     int kase = 0;
    56     memset(dp,-1,sizeof(dp));
    57     //solve(1000000000);
    58     while (t--)
    59     {
    60         int a,b;
    61         scanf("%d%d",&a,&b);
    62         ans = cal(a);
    63         //printf("%d
    ",ans);
    64         printf("Case #%d: %d
    ",++kase,solve(b));
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    锚点
    autoLayout
    基础动画
    核心动画
    get和post的区别
    block的定义及使用
    传值-自定义构造函数传值
    字符串
    字典与可变字典
    RabbitMQ的可视化界面进行操作
  • 原文地址:https://www.cnblogs.com/kickit/p/9028706.html
Copyright © 2011-2022 走看看