标签:
定义幸运数字为有
定义近似幸运数字为有
然后现在给你
一道恶心的
这种题目显然都是转化成求
显然根据位数我们可以分类:
然后如果
如果
那么如果是偶数位,假设位数为
我们发现,现在这个问题的区间中的数的位数都是相同的,然后我们分开考虑前
我们令
然后我们令
然后就是三个的初值:
转移方程和输出答案详见程序吧,感觉很难讲啊。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
long long A,B;
int F[20]={0};
long long counts(int lenth,int num[])
{
long long returnd=0;
int F1[20][50][10][10][2]={{{{{0}}}}};
int F2[20][50][10][10][2]={{{{{0}}}}};
int F3[20][50][10][10][2]={{{{{0}}}}};
F1[0][0][0][0][1]=F2[0][0][0][0][1]=F3[0][0][0][0][0]=1;
for(int i=0;i<(lenth>>1);i++)
{
for(int ss=0;ss<=i*9;ss++)
{
for(int p=0;p<=9;p++)
for(int q=0;q<=9;q++)
{
for(int j=(i+1==1);j<=9;j++)
{
if(j<=num[i+1])
F1[i+1][ss+j][max(p,j-(i+1==1))][max(q,9-j)][j==num[i+1]]+=F1[i][ss][p][q][1];
F1[i+1][ss+j][max(p,j-(i+1==1))][max(q,9-j)][0]+=F1[i][ss][p][q][0];
}
}
}
}
for(int i=0;i<(lenth>>1);i++)
{
for(int ss=0;ss<=i*9;ss++)
{
for(int p=0;p<=9;p++)
for(int q=0;q<=9;q++)
{
for(int j=0;j<=9;j++)
{
if(j<=num[i+1+(lenth>>1)])
F2[i+1][ss+j][max(p,j)][max(q,9-j)][j==num[i+1+(lenth>>1)]]+=F2[i][ss][p][q][1];
F2[i+1][ss+j][max(p,j)][max(q,9-j)][0]+=F2[i][ss][p][q][0];
}
}
}
}
for(int i=0;i<(lenth>>1);i++)
{
for(int ss=0;ss<=i*9;ss++)
{
for(int p=0;p<=9;p++)
for(int q=0;q<=9;q++)
{
for(int j=0;j<=9;j++)
{
if(j<=num[i+1+(lenth>>1)])
F3[i+1][ss+j][max(p,j)][max(q,9-j)][j==num[i+1+(lenth>>1)]]+=F3[i][ss][p][q][1];
F3[i+1][ss+j][max(p,j)][max(q,9-j)][0]+=F3[i][ss][p][q][0];
}
}
}
}
for(int ss=0;ss<=(lenth>>1)*9;ss++)
{
for(int p1=0;p1<=9;p1++)
for(int q1=0;q1<=9;q1++)
for(int p2=0;p2<=9;p2++)
for(int q2=0;q2<=9;q2++)
{
int Max=max(p1,q2);
for(int g=ss+1;g<=ss+Max;g++)
{
returnd+=F1[(lenth>>1)][g][p1][q1][1]*(F2[(lenth>>1)][ss][p2][q2][0]+F2[(lenth>>1)][ss][p2][q2][1]);
returnd+=F1[(lenth>>1)][g][p1][q1][0]*F3[(lenth>>1)][ss][p2][q2][0];
}
Max=max(q1,p2);
for(int g=max(0,ss-Max);g<ss;g++)
{
returnd+=F1[(lenth>>1)][g][p1][q1][1]*(F2[(lenth>>1)][ss][p2][q2][0]+F2[(lenth>>1)][ss][p2][q2][1]);
returnd+=F1[(lenth>>1)][g][p1][q1][0]*F3[(lenth>>1)][ss][p2][q2][0];
}
}
}
return returnd;
}
long long Getans(long long K)
{
int num[20]={0};
int lenth=0;
long long returnd=0;
for(;K>0;)
{
num[++lenth]=K%10;
K/=10;
}
for(int i=2;i<lenth;i+=2)
returnd+=F[i];
reverse(num+1,num+lenth+1);
if(!(lenth&1) && lenth>0)
returnd+=counts(lenth,num);
return returnd;
}
int main()
{
F[2]=81;F[4]=7389;F[6]=676133;F[8]=62563644;
cin>>A>>B;
long long ans=Getans(B)-Getans(A-1);
cout<<ans<<endl;
return 0;
}
标签:
原文地址:http://blog.csdn.net/qq_21995319/article/details/46309849