【HDU.2089 题意】
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
【解题方法】数位DP。dp[i][j]代表当前i位并且首位为j的最大方案!
【AC code】
#include<cstdio>
#include<cstring>
#include <iostream>
#define M 10
int dp[M][M];
using namespace std;
void init()
{
dp[0][0]=1;
for(int i=1; i<=6; i++)
{
for(int j=0; j<=9; j++)//枚举第i位
{
for(int k=0; k<=9; k++)//枚举第i-1位
{
if(j==4||k==4) continue;
if(k==2&&j==6) continue;
//if(k==6&&j==2) continue;
dp[i][j]+=dp[i-1][k];
}
}
}
}
int num[10];
int solve(int n)
{
int t=0;
memset(num,0,sizeof(num));
while(n)
{
num[++t]=n%10;
n/=10;
}
int ans=0;
for(int i=t; i>=1; i--)
{
for(int j=0; j<num[i]; j++)
{
if(j==4) continue;
if(num[i+1]==6&&j==2) continue;
ans+=dp[i][j];
}
if(num[i]==4||(num[i]==2&&num[i+1]==6)) break;
}
return ans;
}
int main()
{
int l,r;
init();
while(scanf("%d%d",&l,&r)!=EOF)
{
if(l==0&&r==0) break;
printf("%d\n",solve(r+1)-solve(l));
}
}
【HDU.3555】 实际上就是上个题的逆过程了。
【AC code】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define M 30
#define ll __int64
ll dp[M][10];
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1; i<30; i++)
{
for(int j=0; j<=9; j++)//第i位
{
for(int k=0; k<=9; k++)//第i-1位
{
if(j==4&&k==9) continue;
dp[i][j]+=dp[i-1][k];
}
}
}
}
int num[25];
ll solve(ll n)
{
int t=0;
memset(num,0,sizeof(num));
while(n)
{
num[++t]=n%10;
n/=10;
}
ll ans=0;
for(int i=t; i>=1; i--)
{
for(int j=0; j<num[i]; j++)
{
if(j==9&&num[i+1]==4) continue;
ans+=dp[i][j];
}
if(num[i]==9&&num[i+1]==4) break;
}
return ans;
}
int main()
{
int T;
ll n;
scanf("%d",&T);
init();
while(T--)
{
scanf("%I64d",&n);
printf("%I64d\n",(ll)(n+1)-solve(n+1));
}
}