hdu2089
分析
算是第一次做数位dp吧,算是长见识了吧,思路相当于是把例如3421拆成3000+400+20+1的情况,对于3000,已经预处理了0-2999的结果,直接加上,3符合要求,所以看400,对于400,已经与处理了0-399的情况,直接加上,但4不符合要求,所以之后的就不看了,相当于看了0-3399的情况。对于预处理就是枚举每一位,枚举每一位的数,枚举前一位的数。
题目
http://acm.hdu.edu.cn/showproblem.php?pid=2089
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
using namespace std;
int dp[10][10];
void init()
{
for(int i=0; i<10; i++)
dp[1][i]=1;
dp[1][4]=0;
for(int i=2; i<=7; i++)
{
for(int j=0; j<10; j++)
{
for(int k=0; k<10; k++)
{
if(j!=4&&!(j==6&&k==2))
dp[i][j] += dp[i-1][k];
}
}
}
}
int solve(int n)
{
int digit[10];
int len=0;
int ans=0;
while(n>0)
{
digit[++len]=n%10;
n/=10;
}
digit[len+1]=0;
for(int i=len; i>0; i--)
{
for(int j=0; j<digit[i]; j++)
{
if(j!=4&&!(digit[i+1]==6&&j==2))
ans+=dp[i][j];
}
if(digit[i]==4||(digit[i]==2&&digit[i+1]==6))
break;
}
return ans;
}
int main()
{
init();
int l,r;
while(cin>>l>>r)
{
if(l+r==0)
break;
else
cout<<solve(r+1)-solve(l)<<endl;
}
return 0;
}