hdu3555
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
using namespace std;
__int64 dp[30][4];
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1; i<=20; i++)
{
dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
//①:dp[i-1][0]*10代表当前可选择0-9十个数 ②:dp[i-1][1]当前以9开头的数的个数。
//③dp[i-1][0]*10-dp[i-1][1]代表不包含49的个数。
dp[i][1]=dp[i-1][0];
//①dp[i-1][0]代表以9开头的个数的数目
dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
//以49开头的个数(分为两种情况:①dp[i][2]:x49xxx ②当第一个x为4时满足条件dp[i][1]x9xxxx
}
}
int main()
{
int T,len,flag,num[50];
__int64 t,ans;
init();
scanf("%d",&T);
while(T--)
{
len=flag=ans=0;
scanf("%I64d",&t);
t++;
memset(num,0,sizeof(num));
while(t)
{
num[++len]=t%10;
t/=10;
}
int g=0;
for(int i=len; i>0; i--)
{
ans+=num[i]*dp[i-1][2];//开头为x49的个数
if(flag)
{
ans+=dp[i-1][0]*num[i];//开头为49的个数
}
if(!flag&&num[i]>4)
{
ans+=dp[i-1][1];//开头为x9(x>4)的个数
}
if(g==4&&num[i]==9)
{
flag=1;//判断。
}
g=num[i];
}
printf("%I64d\n",ans);
}
return 0;
}
hdu2089
数据比较弱:①可以暴搜②可以用数位DP:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
using namespace std;
int dp[1000010];
bool f(int i)
{
while(i)
{
if(i%10==4||i%100==62)
return 1;
i/=10;
}
return 0;
}
int main()
{
int n,m;
int ans,count;
memset(dp,0,sizeof(dp));
for(int i=1; i<1000000; i++)
if(f(i))
dp[i]=1;
while(scanf("%d%d",&n,&m))
{
ans=0;
if(n==0&&m==0)
break;
for(int i=n; i<=m; i++)
if(dp[i]==0)
ans++;
printf("%d\n",ans);
}
return 0;
}
//该题分为三个状态:
//① 不含有不吉利的 ② 不含有 不吉利 但是以2开头的 ③ 含有不吉利的
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
int dp[15][4];
int nu[20];
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1; i<=9; i++)
{
//不含不吉利的数的个数:去掉①含有4的②含有62的
dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
//不含有不吉利的数的个数:以2开头的数的个数
dp[i][1]=dp[i-1][0];
//含有不吉利的数的个数:①含有62的个数②以4开头的个数
dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0];
}
}
int ANS(int num)
{
memset(nu,0,sizeof(nu));
int len=0;
int ans=0;
int tem=num;
while(num)
{
nu[++len]=num%10;
num/=10;
}
int flag=0,last=0;
for(int i=len; i>0; i--)
{
ans+=dp[i-1][2]*nu[i];//不吉利的数
if(flag)
{
ans+=dp[i-1][0]*nu[i];//前面已经出现了不吉利的数
}
else
{
if(nu[i]>4)
ans+=dp[i-1][0];
if(nu[i]>6)
ans+=dp[i-1][1];
if(last==6&&nu[i]>2)
ans+=dp[i][1];
}
if(last==6&&nu[i]==2||nu[i]==4)
flag=1;
last=nu[i];
}
return tem-ans;
}
int main()
{
int n,m;
init();
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
printf("%d\n",ANS(m+1)-ANS(n));
}
return 0;
}