首页 > 其他 > 详细

【hdu2089】不要62

时间:2017-10-25 22:13:08      阅读:246      评论:0      收藏:0      [点我收藏+]

惊奇地发现今天居然和dalao的题单重了不少23333333333333

这是我第一次做数位dp,感觉这个题目还是比较兹磁的

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int l,r,dp[20][15],a[20];
int dfs(int pos,int las,int fl,bool flag)//pos是当前位置,las是上次选的那个数,fl判断上次选的数是否为6,flag判断pos位上是否有枚举限制 
{
    if(pos==0)//答案成立,返回1 
        return 1;
    if(!flag&&dp[pos][las]!=-1)//如果flag==1的时候也返回,那么像213的时候会使答案偏大 
        return dp[pos][las];
    int ding=(flag)?a[pos]:9;//判断这一位上是否有限制最大能枚举的数 
    int re=0;
    for(int i=0;i<=ding;i++)
    {
        if(i==4||(las==6&&i==2))//不能出现4或者62 
            continue;
        re+=dfs(pos-1,i,i==6,flag&&i==a[pos]);
    }
    if(!flag)//如果flag==1说明这一位有限制,并不完全将第pos位上一次选的las的状态完全包含,所以不能赋值 
        dp[pos][las]=re;
    return re;
}
int solve(int x)
{
    int pos=0;
    while(x>0)//先拆分成一位位的数字 
        a[++pos]=x%10,x/=10;
    return dfs(pos,-1,0,1);//flag初始设为0是因为数位长度+1位确实是0 
}
int main()
{
    memset(dp,-1,sizeof(dp));//每次输入的只是不同的数据范围,但是不会影响dp数组的答案,所以只初始化一遍就好 
    while(~scanf("%d%d",&l,&r))
    {
        if(l==0&&r==0)
            break;
        printf("%d\n",solve(r)-solve(l-1));//l也被包含在答案区间一部分 
    }
}

 

【hdu2089】不要62

原文:http://www.cnblogs.com/Loi-dfkdsmbd/p/7732564.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!