【数位DP】不要62 HDU2089

来源:互联网 发布:我的世界枪械js手机版 编辑:程序博客网 时间:2024/05/21 12:50

不要62

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11608    Accepted Submission(s): 3611



Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
 

Input
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
 

Output
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
 

Sample Input
1 1000 0
 

Sample Output
80
 






windy数虽然是yy出来的,但是代码大多数都是从题解里面看来的,这一题又更新了一下代码(统一了一下~)


具体说说dfs模块

有4个参数:

1  pos             : 当前第几位(由于在num数组中是倒着存的,所以调用时带入len)
2  d(down)     : 前面的(高位)数字是否抵着下界
3  u(up)          : 前面的(高位)数字是否抵着上界
4  last             : 上一位的数字是什么


具体解释一下 d 和 u ,比如128~256

当我们枚举第一位为1的时候,它就抵着下界了,也就是下一位要从2开始美剧

如果我们第一位枚举的2,它就抵着上界了,也就是第二位最多枚举到5


那我们调用的时候应该带入true还是false呢?

我们这样看,比如128~256,我们把它看成0128~0256,也就是我们强行选好最高位为0,也就是既抵着上界也抵着下界

所以调用的时候应为 dfs(len,1,1,0);


测评情况(HDU)




C++ AC Code

/*http://blog.csdn.net/jiangzh7By Jiangzh*/#include<cstdio>#include<cstring>#define max(a,b) ((a)>(b)?(a):(b))int A,B;int L[20],R[20],len;int f[15][2][2][15];void predoing(int a,int *num){int le=0;while(a){num[++le]=a%10;a/=10;}len=max(len,le);}int dfs(int pos,bool d,bool u,int last){if(pos==0) return 1;int &res=f[pos][d][u][last];if(res!=-1) return res;int st=d?L[pos]:0;int ed=u?R[pos]:9;res=0;for(int i=st;i<=ed;i++){if(i==4) continue;if(i==2&&last==6) continue;res+=dfs(pos-1,d&&i==L[pos],u&&i==R[pos],i);}return res;}int main(){freopen("hdu2089.in","r",stdin);freopen("hdu2089.out","w",stdout);while(scanf("%d%d",&A,&B)==2&&A&&B){memset(f,-1,sizeof(f));len=0;memset(L,0,sizeof(L)); predoing(A,L);memset(R,0,sizeof(R)); predoing(B,R);printf("%d\n",dfs(len,1,1,0));}return 0;}



原创粉丝点击