zoukankan      html  css  js  c++  java
  • HDU

    咸鱼了一个月,不能在闲下去了。

    第一次做数位dp,好难!虽然是入门题。

    https://vjudge.net/problem/HDU-2089

    思路:从高到地枚举每一位可能出现的数字,在设置一个变量state表示当前位前面是否是6,那么dp[len][state]代表长度为len状态为staste时的解的个数。首先要把所求的数拆开,这样做的目的是知道每一位能取的最大值。再设置一个参数fp表示当前位选择的数字是不是当前位可以取到的最大值。举个例子,如果我们要求6734,那么我们肯定要求6xxx,5xxx,4xxx,3xxx,......(加法原理)在这种情况下每一种取法的后三位的答案一定是一样的,这种时候直接加起来就好(dp[len-1][state]),但是如果首位是6就有点特殊了这个时候不能直接加上dp[i-1][state]了,因为后三位有了限制不可以取到0-999。具体看代码就懂了。

    #include<bits/stdc++.h>
    #define _for(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    const int mod =1e6+7;
    double esp=1e-6;
    int INF =0x3f3f3f3f;
    const int inf = 1<<28;
    const int MAXN=1e5+10;
    int p[10];
    int dp[10][2];
    int dfs(int len,bool state,bool fp)
    {
        if(len==0)return 1;
        if(!fp&&dp[len][state]!=-1)return dp[len][state];//记忆化
        int fpmax=fp?p[len]:9;//当前位取到的最大值
        int ans=0;
        for(int i=0;i<=fpmax;i++)
        {
            if(i==4||(state&&i==2))continue;
            ans+=dfs(len-1,i==6,fp&&i==fpmax);
        }
        if(!fp)dp[len][state]=ans;
        return ans;
    }
    int solve(int n)
    {
        int len=0;
        while(n)
        {
            p[++len]=n%10;
            n/=10;
        }
        return dfs(len,0,1);
    
    }
    int main()
    {
        int a,b;
        memset(dp,-1,sizeof(dp));
        while(~scanf("%d%d",&a,&b))
        {
            if(a==0&&b==0)break;
            cout<<solve(b)-solve(a-1)<<endl;
        }
    }
  • 相关阅读:
    计算十位数以内的数的反数
    用Python做一个简单的小游戏
    Python的发展历史及其前景
    监控相关总结
    前端css学习_Day15
    常用命令总结
    mysql常用命令总结
    Python之Paramiko、前端之html学习_Day14
    Python操作redis、memcache和ORM框架_Day13
    Python连接msyql、redis学习_Day12
  • 原文地址:https://www.cnblogs.com/kayiko/p/12288230.html
Copyright © 2011-2022 走看看