zoukankan      html  css  js  c++  java
  • 数位dp

    含有一个数字(4)或者一个数(62)

    对于找这些问题就是:首先dp[]的一维就是这个数的位数,1类问题本质就是在寻找某个状态,所以需要加上状态一维,此时dp[][] 就存在了二维, 数位dp实质就是暴力,因为一般的数位dp是借助dfs的搜索方式来完成的,dfs的工作就是像一颗只有主干和根的树,从主干直接去往根部走,先按照一个根以及这个根的一个分支往下走。遇到符合情况的就改变此时的状态,直到pos<0时,dfs完成了一种情况的搜索, 然后记录结果,继续往下一个分支走,当所有的分支遍历过后,工作完成

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <map>
     8 #include <set>
     9 #define ll long long
    10 using namespace std;
    11 const int maxn = 1e5;
    12 ll num[20];///直接找数据范围就行
    13 ll dp[20][3];///一维代表位数,二维代表状态
    14 ll dfs(int pos,int state,int limt)
    15 {
    16     if(pos < 0)///搜索完所有的位数时返回
    17         return state == 2;
    18     if(!limt && dp[pos][state]!=-1)///记忆化搜索的返回条件,大量节省时间,没有这一步记忆化就起不上作用了
    19         return dp[pos][state];
    20     int up = limt?num[pos]:9;/// up 在这一位上的最大值
    21     ll ans=0;
    22     for(int i=0; i<=up; i++)
    23     {
    24         if(i == 4 || state == 2 || i==2 && state == 1)
    25             ans += dfs(pos-1, 2, i==up&&limt);
    26         else if(i==6)
    27             ans += dfs(pos-1, 1, i==up&&limt);
    28         else
    29             ans += dfs(pos-1, 0, i==up&&limt);
    30         ///关于i==up&&limt这一步的理解,现在的条件是不是满足这个式子,yes or no?1:0;
    31         
    32         ///和上面判断条件一样,形式不一样,意思一样
    33         /**if(i == 4 || state == 2 || i==2 && state == 1)
    34             state2 = 2;///这个状态是重新定义的,不能在state上面直接改,否则后面的for循环的state状态就不符合原来的状态了
    35         else if(i==6)
    36             state2 = 1;
    37         else
    38             state2 = 0;
    39         ans += dfs(pos-1, state2, i==up&&limt);*/
    40     }
    41     ///记忆化需要先记忆,在调用,这里就是
    42     if(!limt)///没达到最大值时,调用,因为每个情况的最大值不同,最大值处的值不存在记录意义
    43         dp[pos][state] = ans;
    44     return ans;
    45 }
    46 
    47 ll Solve(ll as)
    48 {
    49     int len = 0;
    50     memset(dp, -1, sizeof(dp));
    51     memset(num, -1, sizeof(num));
    52     while(as)
    53     {
    54         num[len++] = as%10;
    55         as /= 10;
    56     }
    57     return dfs(len-1, 0, 1);///*****
    58 }
    59 
    60 int main()
    61 {
    62     ll n, m;
    63     while(scanf("%lld %lld", &n, &m),n+m)
    64     {
    65         ll ans = Solve(m) - Solve(n-1);
    66         cout<<m - n + 1 - ans<<endl;
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    wp8使用mvvm模式简单例子(二)---登陆功能,事件触发
    wp8使用mvvm模式简单例子
    win8.1使用WP8SDK出现Windows Phone Emulator无法启动的问题解决方案
    asp.net原理笔记----页面控件类型,页面状况和asp.net编译过程
    asp.net生命周期
    asp.net服务器数据源控件学习笔记
    AJax学习笔记
    asp.net敏感词过滤
    网上书城总结笔记
    在自己的网站上使用RSS订阅功能
  • 原文地址:https://www.cnblogs.com/zznu17-091041/p/9364644.html
Copyright © 2011-2022 走看看