zoukankan      html  css  js  c++  java
  • 不要62 hdu 2089 dfs记忆化搜索

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089

    题意:

    给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数

    思路:

    数位dp中的 dfs 记忆化搜索方法解。

    模板:

    int dfs(int i, int s, bool e) {  
        if (i==-1) return s==target_s;  
        if (!e && f[i][s] != -1) return f[i][s];  
        int res = 0;  
        int u = e?num[i]:9;  
        for (int d = first?1:0; d <= u; ++d)  
            res += dfs(i-1, new_s(s, d), e&&d==u);  
        return e?res:f[i][s]=res;  
    }  

    f为记忆化数组 ;

    i为当前处理串的第i位(权重表示法,也即后面剩下i+1位待填数);

    s为之前数字的状态(如果要求后面的数满足什么状态,也可以再记一个目标状态t之类,for的时候枚举下t);

    e表示之前的数是否是上界的前缀(即后面的数能否任意填)。

    代码如下:

    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int a, b, shu[20], dp[20][2];
    
    int dfs(int len, bool if6, bool shangxian)
    {
        if (len == 0)        return 1;
        if (!shangxian && dp[len][if6])        return dp[len][if6];
        int cnt = 0, maxx = (shangxian ? shu[len] : 9);
        for (int i = 0; i <= maxx; i++)
        {
            if (if6 && i == 2 || i == 4)
                continue;
            cnt += dfs(len - 1, i == 6, shangxian && i == maxx);
        }
        return shangxian ? cnt : dp[len][if6] = cnt;
    }
    
    int solve(int x)
    {
        memset(shu, 0, sizeof(shu));
        int k = 0;
        while (x)
        {
            shu[++k] = x % 10;  
            x /= 10;
        }
        return dfs(k, false, true);
    }
    
    int main()
    {
        while (cin >> a >> b, a&&b)
            cout << solve(b) - solve(a - 1) << endl;
        
        return 0;
    }

    感谢您的阅读,生活愉快~

  • 相关阅读:
    rt_list_entry() 函数
    替换空格
    跳台阶
    斐波那契数列
    基于5221码的同步十进制加法计数器
    强连通分量+Tarjia+缩点
    次小生成树
    差分约束
    P1547 Out of Hay
    P1197 [JSOI2008]星球大战
  • 原文地址:https://www.cnblogs.com/lv-anchoret/p/8466827.html
Copyright © 2011-2022 走看看