您的位置:首页 > 理论基础 > 计算机网络

hdu 5898 odd-even number 2016ACM/ICPC沈阳赛区网络赛1007

2016-09-18 22:49 495 查看
Problem Description

For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).

 

Input

First line a t,then t cases.every line contains two integers L and R.

 

Output

Print the output for each case on one line in the format as shown below.

 

Sample Input

2
1 100
110 220

 

Sample Output

Case #1: 29
Case #2: 36

数位DP。

f[len][p1][sx]表示len位,上一位数字是p1,和p1相同奇偶性的出现了sx次的方案数

记得单独特判前导0

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
long long f[21][10][21];
int a[21];
inline long long dfs(int len,int p1,int sx,bool lim,bool lim2)
{
if(len==0)
{
if(sx%2!=p1%2&&!lim2)
return 1;
return 0;
}
if(!lim&&f[len][p1][sx]!=-1)
return f[len][p1][sx];
int i;
int limit;
if(lim)
limit=a[len];
else
limit=9;
long long ans=0;
for(i=0;i<=limit;i++)
{
int s;
if(lim2&&i==0)
s=0;
else if(i%2==p1%2)
s=sx+1;
else if(sx%2!=p1%2||lim2&&i!=0)
s=1;
else if(sx!=0||!lim)
continue;
ans+=dfs(len-1,i,s,lim&&i==a[len],lim2&&i==0);
}
if(!lim)
f[len][p1][sx]=ans;
return ans;
}
inline long long cale(long long x)
{
int len=0;
while(x!=0)
{
len++;
a[len]=x%(long long)10;
x=x/(long long)10;
}
int i,j;
long long ans=0;
ans+=dfs(len,0,0,true,true);
return ans;
}
int main()
{
int k=0;
int T;
scanf("%d",&T);
memset(f,-1,sizeof(f));
while(T>0)
{
T--;
k++;
long long l,r;
scanf("%lld%lld",&l,&r);
if(l!=(long long)10000000000)
printf("Case #%d: %lld\n",k,cale(r)-cale(l-1));
else
printf("Case #%d: %lld\n",k,cale(r));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数位DP