zoukankan      html  css  js  c++  java
  • HDU

    求出在([1, b])里有多少个数字的(F(i) leq F(a))

    首先算出(F(a))的值,然后套一下数位dp板子即可
    同时记录其权值变化,对于每一个base就是(2^{pos})
    但是选择记录当前权值然后最后比较是否小于等于(F(a))是不行的
    因为记忆化搜索就会记录有多少个权值是小于第一个(F(a)),所以需要改变一下。

    设初始值为(F(a)),然后去减每位的权值,最后判断权值是否大于等于0即可。

    记住,记忆化搜索的话,就必须保持记录的值是同一条件的

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int dp[10][4600];
    int a[20];
    int base[30];
    int maxx = 0;
    int dfs(int pos, bool limit, int now){
        if(pos == -1) return now >= 0;
        if(now < 0) return 0;
        if(!limit && now >= 0 && dp[pos][now] != -1) return dp[pos][now];
        int up = limit ? a[pos] : 9;
        int tmp = 0;
        for(int i = 0; i <= up; i++) {
            tmp += dfs(pos - 1, limit && i == up, now - i * base[pos]);
        }
        if(!limit && now >= 0) dp[pos][now] = tmp;
        return tmp;
    }
    int solve(int n){
        int pos = 0;
        while(n){
            a[pos++] = n % 10;
            n /= 10;
        }
        return dfs(pos - 1, 1, maxx);
    }
    void init(int n){
        int base = 1;
        while(n){
            maxx += n % 10 * base;
            n /= 10;
            base *= 2;
        }
    }
    int main(){
        for(int i = 0; i <= 30; i++) base[i] = 1 << i;
        int t;
        memset(dp, -1, sizeof(dp));
        scanf("%d", &t);
        for(int i = 1; i <= t; i++) {
            maxx = 0;
            int a, b;
            scanf("%d%d", &a, &b);
            init(a);
            printf("Case #%d: %d
    ", i, solve(b));
        }
        return 0;
    }
    
  • 相关阅读:
    QTableWidget的使用和美工总结
    pyqt下QTableWidget使用方法小结(转)
    改变QTableWidget 行高(转)
    Qt中 文件对话框QFileDialog 的使用
    Qt:拖拽图片到QLabel上并显示(转)
    Qt获取组合键(转)
    Qt图片显示效率的比较(转)
    QComboBox用法小列(转)
    TinyXML:一个优秀的C++ XML解析器(转)
    JZOJ 3099. Vigenère密码 NOIP2012
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14107908.html
Copyright © 2011-2022 走看看