题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2089
题目大意:
找出区间
[n,m]
内不含子串62以及4的数字个数
分析:
找不含4的数字直接在向下层dp时遇到
i==4
的情况跳过即可,对于不含62的情况,加一个参数
pre
,记录之前一个数位的情况,若之前为6,且当前要放2,则跳过,按模板dp即可
这题的数据量很小,所以直接暴力也可以,当然一般当做数位dp练手,上手可以先先试试不看模板,敲一发没有额外限制条件的dp,也就是求 0−n 之间数字的个数,然后试着通过增加、修改条件,达成题目的要求
代码:
#include <cstdio>
#include <cstring>
typedef long long ll;
int dp[30][2];
int a[50],pos;
ll dfs(int pos,int pre,bool sta,bool limit)
{
if (pos==-1)
return 1;
if (!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
int up = limit?a[pos]:9;
ll ans = 0;
for (int i = 0 ; i <= up ; i ++)
{
if (pre==6&&i==2)
continue;
if (i==4)
continue;
ans += dfs(pos-1,i,i==6,limit&&i==pos[a]);
}
if (!limit) dp[pos][sta] = ans;
return ans;
}
ll solve(ll n)
{
pos = 0;
while (n)
{
a[pos++] = n%10;
n /= 10;
}
return dfs(pos-1,0,false,true);
}
int main()
{
int n,m;
memset(dp,-1,sizeof(dp));
while (~scanf("%d%d",&n,&m)&&(n||m))
{
if (n>m)
{
n = n^m;
m = n^m;
n = n^m;
}
printf("%lld\n",solve(m)-solve(n-1));
}
}