hdu2089不要62

hdu2089不要62

中文题就不写题意了,也不是很难理解。
主要用到的数位dp的方法,一种记忆化搜索的dp方法
刚刚开始学还不是很熟悉这个模板,所以代码不是自己写的,等等我会再去写几遍,给了很多注释来帮助理解,希望能对你有帮助。

# include <iostream>
# include <stdio.h>
# include <cstring>
# include <string>

using namespace std;
typedef long long LL;

int a[20];//存储每一位的限制。
int dp[20][2];
/*
    dp[pos][sta]
    pos:当前是第几位
    sta前一位是否为6:
        为6为0
        不为6为1
*/
int dfs(int pos, int pre, int sta,bool limit)   {
    /*
        pos:当前在第几位
        pre:上一位的数字是什么
        sta:上一位是否是6
        limit:当前位是否要遵循a数组的限制。
    */
    if(pos == -1)   return 1;//当前位为-1位,即不存在的。。直接返回就好,相当于在第0位返回1
    if(!limit && dp[pos][sta] != -1) return dp[pos][sta];//当前位不被限制,且dp中已存在值,则直接返回这个值
    int up = limit ? a[pos] : 9;//判断是否有限制,没有就直接枚举到9
    int tmp = 0;//把当前情况下的所有情况个数存下来
    for(int i = 0; i <= up; i++)    {
        if(pre == 6 && i == 2)  continue;
        if(i == 4) continue;
        tmp += dfs(pos-1,i,i == 6, limit && i == a[pos]);
    }
    if(!limit) dp[pos][sta] = tmp;//当前位不被限制,则记忆化当前值。
    /*
        为什么要区分当前位是否被限制来判断是否记忆化?
            因为当前位是否被限制是不在二维dp的状态里的,这里的两种状态明显值是不同的,
            记忆化过程中,不被限制时的值更能节省时间,被限制的情况在搜索中是少数,所以
            其实不会太影响程序的运行速度,当然,可以给出三维dp的状态,只不过在本题目中
            没有必要。
    */
    return tmp;
}

int solve(int x)    {//解决的问题是:从1到x有多少个车牌满足条件
    int pos = 0;
    while(x)    {
        a[pos++] = x%10;
        x /= 10;
    }
    return dfs(pos-1,-1,0,true);
}

int main()  {
    int le,ri;
    while(~scanf("%d%d",&le,&ri) && le+ri)  {
        memset(dp,-1,sizeof(dp));
        printf("%d\n",solve(ri) - solve(le-1));
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值