zoukankan      html  css  js  c++  java
  • hdu-2089 不要62 基础DP 模板

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

    数位DP的思想时预处理以x开头长度为len的数(例如 x000~x999)的所有情况。给出一个数,可以在log10(n)的复杂度下完成分解。

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const LL N = 1000015;
    const LL INF = 100000009;
    LL dp[8][10];//bit,num
    void init()
    {
        memset(dp, 0, sizeof dp);//初始化为0
        LL sum = 0, temp = 0;//用sum维护上一层的总和,当传递不是简单的和传递时考虑用多维sum维护或者暴力
        for (int i = 0; i < 10; i++)
            dp[0][i] = 1;
        dp[0][4] = 0;
        sum = 9;
        for (int len = 1; len < 8; len++)
        {
            temp = 0;//临时记录本层
            for (int i = 0; i < 10; i++)
            {
                if (i == 4)continue;
                dp[len][i] = sum;
                if (i == 6) dp[len][i] -= dp[len - 1][2];
                temp += dp[len][i];
            }
            sum = temp;
        }
    }
    LL arr[100];//当前求解的数的分解
    LL dfs(LL pos, LL pre)
    {
        if (pos == -1)return 0;//尾部
        LL num = arr[pos];//获取当前数
        LL cnt = 0;//计算以pre为前缀,后面从0~num-1开头的所有情况
        for (int i = 0; i < num; i++)
        {
            if (pre == 6 && i == 2)continue;
            if (i == 4)continue;
            cnt += dp[pos][i];
        }
        if (num == 4)return cnt;
        if (pre == 6 && num == 2)return cnt;
        return cnt + dfs(pos - 1, num);//下一级dfs传递前缀(对于不同题目需要传递的前缀信息不同)
    }
    LL sol(LL x)
    {
        x++;//dfs在求解时,只能解出x-1的所有情况,x需要在递归尾部特判,干脆我们将x++,这样正好求出x
        if (x == 0) return 1;
        LL siz = 0;
        while (x)
            arr[siz++] = x % 10, x /= 10;
        LL ans = 0;
        ans = dfs(siz - 1, -1);
        return ans;
    }
    int main() {
        cin.sync_with_stdio(false);
        LL n, m;
        init();
        while (cin >> n >> m)
        {
            if (n == 0 && m == 0) break;
            cout << sol(m) - sol(n - 1) << endl;
        }
        return 0;
    }
  • 相关阅读:
    Oracle并行操作——从串行到并行
    Log4Net使用指南
    NET开发人员应该要知道
    测试11g压缩性能
    C#不同操作系统下,界面大小不一的原因
    采用nettcp绑定的wcf宿主到iis7
    Packaging Oracle Data Access Components into .Net projects
    Operating System Property Values
    【转】《Effective C#中文版:改善C#程序的50种方法》读书笔记
    解决.svc 无法解析
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/7490258.html
Copyright © 2011-2022 走看看