链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555
题意:求范围内含有49的数的个数。
思路:用dfs写的,也可以正常写,如dp(一)中那样。模板题,在dp(二)中已经提到。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
long long dp[30][2];
int num[30];
long long shu[20];
long long dfs(int len,bool shi4,bool dao,bool ok) // len数字长度,shi4表示前一个数是4,dao表示前一个数已经到最大值,ok表示之前已经有49
{
if(len <= 0) return ok;
if(!dao && ok) return dao?shu[len]+1:shu[len]; // 如果前面已经出现过49,后面的数都满足
if(!dao && dp[len][shi4] != -1) return dp[len][shi4];
int over = dao?num[len]:9;
long long sum = 0;
for(int i = 0;i <= over;i++){
sum += dfs(len-1,i==4,i==over&&dao,ok||(shi4&&i==9));
}
if(!dao) dp[len][shi4] = sum;
return sum;
}
long long shudp(long long number)
{
int len = 0;
memset(num,0,sizeof(num));
while(number){
num[++len] = number%10;
number /= 10;
}
return dfs(len,false,true,false);
}
void init()
{
memset(dp,-1,sizeof(dp));
shu[0] = 1;
for(int i = 1;i < 20;i++){ //记录不同长度下的数
shu[i] = shu[i-1]*10;
}
}
int main()
{
int t;
init();
while(~scanf("%d",&t)){
while(t--){
long long number;
scanf("%lld",&number);
printf("%lld\n",shudp(number));
}
}
return 0;
}