2089:求区间内不含62 和4的数字的个数
简单的数位dp,数位dp也就是搜索,按照位数来搜的,所以时间上应该是很快的,对于搜索,确定好当前所在长度(也就是搜到的当前数的长度),约束条件,还有是不是最后一个这个条件,
代码+解释
/* I believe xiaoxuzizhucan*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#include<math.h>
#include <queue>
long long a[100];
long long dp[200][5];
//dfs(当前所在的位数,上一个数的i是不是等于6,是不是最后一位)
long long dfs(long long pos,long long have,long long flag)
{
if(pos==0)//如果长度为0,也就是所搜到最后了,所以返回1,也就是这个数不含4和62,一位如果含有4和62,那就不会搜索到这一步,在下面的搜素过程中就continue了
{
return 1;
}
if(flag==0&&dp[pos][have]!=-1)//同理,剪枝头,我不是很懂。。其实删去应该也是对的吧,
{
return dp[pos][have];
}
long long sum=0;
long long end=flag?a[pos]:9;//求该为所能搜索的最大值
for(long long i=0; i<=end; i++)
{
if(i==4||have&&i==2)//如果当前为为4,或者上一个状态为6并且这一个状态为2,也就是出现4或者出现62,那么就不要你继续往下搜索了。
continue;
sum+=dfs(pos-1,i==6,flag&&i==end);//如果当前没有出现过4和62,然后就判断当前位是不是等于6,
}
if(flag==0)//入股不是最后一位,那么久赋值,方便上面剪枝使用
dp[pos][have]=sum;
return sum;
}
long long solve(long long n)
{
long long len=1;
while(n)
{
a[len++]=n%10;
n/=10;
}
//printf("%d\n",len);
return dfs(len-1,0,1);
}
int main()
{
long long n,m;
memset(dp,-1,sizeof(dp));
while(scanf("%I64d%I64d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
printf("%I64d\n",solve(m)-solve(n-1));
}
}
3555:
题意,让你找小于n的数中含有49的个数有多少。
同样也是很裸的数位dp,就不断地搜索就好了呗,想好状态变化就好了。
代码+解释
/* I believe xiaoxuzizhucan*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
#include<math.h>
long long a[150];
long long dp[150][5];
//dfs(当前数的长度,上一位是不是6,是不是最后一位)
long long dfs(long long pos,long long have ,long long flag)
{
if(pos==0)//长度为0如果have==2,也就是出现过49就返回1,表述出现了一个
{
if(have==2)
return 1;
else return 0;
}
if(flag==0&&dp[pos][have]!=-1)//剪枝,也就是说如果当前位不是最后一位,并且被访问过,就直接返回
return dp[pos][have];
long long end=flag?a[pos]:9;//确定当前为最大值,
long long sum=0;
for(long long i=0; i<=end; i++)
{
long long temphave=have;
if(have==1&&i!=4)//如果上一个是1,这一个不是1,那么就不可能有49
temphave=0;
if(have==0&&i==4)//如果上一个不可能是49,但是这一个是4,那么标记为1,也就是表示上一个状态为4
temphave=1;
if(have==1&&i==9)//如果上一个状态为4(have=1)并且这个状态为9,那么就出现49了,所以have==2代表49出现过
temphave=2;
sum+=dfs(pos-1,temphave,flag&&i==end);
}
if(flag==0)//若果不是在最后一位
dp[pos][have]=sum;
return sum;
}
long long suan(long long x)
{
long long len=1;
while(x)
{
a[len++]=x%10;
x/=10;
}
return dfs(len-1,0,1);
}
int main()
{
long long test;
memset(dp,-1,sizeof(dp));
scanf("%I64d",&test);
while(test--)
{
long long n;
scanf("%I64d",&n);
printf("%I64d\n",suan(n));
}
}