题目要求就是求出从n到m之间所有不包含4跟62的数目的个数。
参考了别人的文章以后用dfs写的动态规划。
http://blog.csdn.net/dgq8211/article/details/9296953
在dfs过程中加入记忆化搜索。dp(len,top)表示剩余len位的时候最高位是否为6(top==1为是)时,可以有的数字的个数。dfs(len,top,flag)中len表示剩余len位,top表示最高位是否为6,flag记录这一位是否能取到9。使用flag的原因是在遍历的时候,下一位能取到的最大值(是9还是digit(len-1))取决于这一位的数,假如这一位能取到9,那么下一位不论怎么取,都不会超过限定的值,另一种情况是如果这一位不能取到9,但是这一位目前取到的值比限定的值(digit(len))要小,那么下一位一样可以取到9。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int digit[9];
int dp[9][10];
int dfs(int len,int top,int flag){
if(len==0)return 1;
if(flag&&dp[len][top]!=-1)return dp[len][top];
int fmax=flag?9:digit[len];
int ret=0;
for(int i=0;i<=fmax;++i){
if(i==4)continue;
if(top&&(i==2))continue;
ret=ret+dfs(len-1,i==6,flag||i<fmax);
}
if(flag)dp[len][top]=ret;
return ret;
}
int solve(int n){
int len=1;
while(n){
digit[len++]=n%10;
n/=10;
}
len--;
return dfs(len,false,false);
}
int main(){
int n,m;
while(cin>>n>>m){
memset(dp,-1,sizeof(dp));
if(!n&&!m)break;
cout<<(solve(m)-solve(n-1))<<endl;
}
return 0;
}