hdu 2089 不要62

不要62

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


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 100 0 0
 

Sample Output
  
  
80
 

方法一:

记忆化搜索+数位DP

dp[i][j]:位数为i位,j=0为不含不吉利数字的数的个数,j=1为不含不吉利数字,且最高位为6的数的个数;

 #include<iostream>
 using namespace std;
 #include<string.h>
 int dp[8][2],dight[8];
 int dfs(int pos,int st,bool flag)
 {  int i;
    int ans=0;
    if(pos==-1) return 1;
    if(!flag&&dp[pos][st]!=-1)return dp[pos][st];
    int u=flag?dight[pos]:9;
    for(i=0;i<=u;i++)
    {
        if(i==4||st==1&&i==2)
            continue;
        ans=ans+dfs(pos-1,i==6,flag&&i==u);
    }
    if(!flag)dp[pos][st]=ans;
    return ans;
 }
  int fun(int n)
 {  int i=0;
    int ans;
     while(n)
     {
         dight[i++]=n%10;
         n=n/10;
     }
     dfs(i-1,0,1);
 }
 int main()
 {
     int n,m,i,j;
     while(cin>>n>>m)
     { memset(dp,-1,sizeof(dp));
         if(n==0&&m==0)break;
         cout<<fun(m)-fun(n-1)<<endl;
     }
  return 0;
 }

方法二:

纯数位DP

dp[i][j]:位数为i,且最高位为j的数的个数。

 #include<iostream>
 using namespace std;
 #include<string.h>
 int dp[7][10];
 int fun(int n)
 {
   int dight[10],len=1,i,sum=0,j;
   while(n)
   {
     dight[len++]=n%10;
     n=n/10;
   }
   dight[len]=0;
   for(i=len-1;i>0;i--)
   {
       for(j=0;j<dight[i];j++)
        if(j!=4&&!(j==2&&dight[i+1]==6))
        sum=sum+dp[i][j];
       if(dight[i]==4||dight[i]==2&&dight[i+1]==6)
        break;
   }
   return sum;
 }
 int main()
 {
     int n,m,i,j,k,ans;
      memset(dp,0,sizeof(dp));
         dp[0][0]=1;
         for(i=1;i<7;i++)
            for(j=0;j<=9;j++)
            for(k=0;k<=9;k++)
            if(j!=4&&!(j==6&&k==2))
            dp[i][j]=dp[i][j]+dp[i-1][k];
     while(cin>>n>>m)
     {
         if(n==0&&m==0)break;

         ans=fun(m+1)-fun(n);
         cout<<ans<<endl;
     }
     return 0;
 }





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值