题意:
给定一个区间\([l,r]\)求区间内,有至少三个相邻位数数字相同,且不同时有4和8的数字个数
范围&性质:\(1\le l,r < 10^{11}\)
分析:
不知道写些什么,很裸的数位DP,DFS传参时记录一下:第几位,上一位,上上一位,是否有至少连续3位相同,是否取到上界,是否有4,是否有8
tips:可以记忆化降低复杂度,因为参数较小
代码:
#include<bits/stdc++.h>
using namespace std;
namespace zzc
{
long long l,r;
long long dp[15][15][15][2][2][2][2],num[15],cnt;
long long dfs(int pos,int a,int b,bool ok,bool lim,bool _4,bool _8)
{
if(_4&&_8) return 0;
if(pos<=0) return ok;
if(~dp[pos][a][b][ok][lim][_4][_8]) return dp[pos][a][b][ok][lim][_4][_8];
int tmp=lim?num[pos]:9;
long long res=0;
for(int i=0;i<=tmp;i++)
{
res+=dfs(pos-1,i,a,ok||(i==a&&i==b),lim&&(i==tmp),_4||(i==4),_8||(i==8));
}
return dp[pos][a][b][ok][lim][_4][_8]=res;
}
long long calc(long long x)
{
if(x<1e10) return 0;
memset(dp,-1,sizeof(dp));
cnt=0;
while(x)
{
num[++cnt]=x%10;
x/=10;
}
long long res=0;
for(int i=1;i<=num[cnt];i++)
{
res+=dfs(10,i,0,false,i==num[cnt],i==4,i==8);
}
return res;
}
void work()
{
cin>>l>>r;
cout<<calc(r)-calc(l-1)<<endl;
}
}
int main()
{
zzc::work();
return 0;
}