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

    题目链接:HDU 4734 F(x)

    题目大意:
    定义十进制数(x)的权值为(F(x)=A_n imes 2^{n-1}+A_{n-1} imes 2^{n-2}+...+A_2 imes 2+A_1 imes 1)(A(i))表示十进制数(x)中第(i)位的数字。
    题目给出(A)(B),求出([0,B])有多少个权值不大于(F(A))的数。

    题解:
    (dp[pos][sum])表示长度为(pos)且权值不大于(sum)的数的个数。
    用记忆化搜索,到最低位若权值仍小于(F(A))则表示该数符合。

    #include <cstring>
    #include <iostream>
    using namespace std;
    #define ll long long
    
    int digit[20];
    ll dp[20][5000], n, m;
    
    int dfs(int pos, int sum, bool limit) {
        if (pos <= 0) return sum >= 0;
        if (sum < 0) return 0; // 已经比F(A)小了就不用往下搜索了
        if (!limit && dp[pos][sum] != -1) return dp[pos][sum]; // 没限制则用记忆化搜索
        int ans = 0;
        int up = limit ? digit[pos] : 9;
        for (int i = 0; i <= up; ++i) {
            ans += dfs(pos - 1, sum - i * (1 << (pos - 1)), limit && i == up);
        }
        if (!limit) dp[pos][sum] = ans;
        return ans;
    }
    
    ll F(ll x) { // F(A)
        ll ans = 0, cnt = 1;
        while (x) {
            ans += x % 10 * cnt;
            cnt *= 2;
            x /= 10;
        }
        return ans;
    }
    
    int cal(ll x) {
        int cnt = 0;
        while (x) {
            digit[++cnt] = x % 10;
            x /= 10;
        }
        return cnt;
    }
    
    int main() {
        int T;
        cin >> T;
        memset(dp, -1, sizeof(dp));
        for (int Case = 1; Case <= T; ++Case) {
            cin >> n >> m;
            cout << "Case #" << Case << ": " << dfs(cal(m), F(n), true) << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    一场由空格引发的错误数据
    ECS服务器搭建Discuz 邮箱设置,报错处理
    MS SQL CASE WHEN 的用法
    sql prompt 缩写 快捷键
    CentOS 防火墙
    docker swarm
    docker machine
    docker-compose 配置
    docker-compsoe & .netcore & nginx
    dockerfile
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/14315374.html
Copyright © 2011-2022 走看看