您的位置:首页 > 其它

【数位DP】HDU 2089 不要62

2016-08-20 10:12 316 查看


不要62
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64u
Submit Status Practice HDU
2089

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的车牌号数,不过这个方案数是不考虑上限的。所以我们在处理输入数据时,从高位开始累计。

为了避免统计超过上限的方案,对于 dp[i][num[i]] (num[i] 表示 上界的第i位数字),我们把它拆分成 dp[i-1][0~num[i-1]-1],至于 dp[i-1][num[i-1]] 以此类推。

最后我们会发现 dp[1][num[1]] 是不会被统计到的 ,也就是说我们统计的是小于上限的方案数,于是我们要注意在统计时将真正的上限加一。

同时,因为我们统计时将 dp[i][num[i]] 拆分成了 dp[i-1][....]  若 num[i],num[i-1] 是连续的 62 ,则之后统计的方案必定不合法,故可以完成统计。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

#define MAXLEN 7
#define MAXNUM 10
#define INF 0x3f3f3f3f
typedef long long int LL;

int L,R;
int dp[MAXLEN+10][MAXNUM+5];

void Init(int n)
{
memset(dp,0,sizeof(dp));

dp[0][0]=1;

for(int i=1;i<=n;++i)
for(int j=0;j<=9;++j)
for(int k=0;k<=9;++k)
if(j!=4&&!(j==6&&k==2))
dp[i][j]+=dp[i-1][k];
}

int Num[MAXLEN+10];
int Len;

void GetNum(int x)
{
memset(Num,0,sizeof(Num));
Len=0;

while(x)
{
Num[++Len]=x%10;
x/=10;
}

return;
}

int GetAns(int x)
{
int ans=0;

GetNum(x);

for(int i=Len;i>0;--i)
{
for(int j=0;j<Num[i];++j)
if(j!=4&&!(Num[i+1]==6&&j==2))
ans+=dp[i][j];

if(Num[i]==4||(Num[i+1]==6&&Num[i]==2))
break;
}

return ans;
}

int main()
{
Init(7);

while(~scanf("%d%d",&L,&R)&&!(!L&&!R))
{
int i,j;
printf("%d\n",GetAns(R+1)-GetAns(L));
}
}

/*
14 14
0 0
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: