您的位置:首页 > 其它

HDU 5898 odd-even number 数位DP

2016-09-18 19:22 375 查看

odd-even number

[align=left][b]Problem Description[/b][/align]
[align=left] [/align]
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).

[b]Input[/b]

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

[align=left][b]Output[/b][/align]
[align=left] [/align]
Print the output for each case on one line in the format as shown below.

[align=left][b]Sample Input[/b][/align]
[align=left] [/align]

2
1 100
110 220

[align=left][b]Sample Output[/b][/align]
[align=left] [/align]

Case #1: 29
Case #2: 36

  


    基础的数位DP

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 600+10, M = 1e2+11, mod = 1e9+7, inf = 0x3fffffff;

LL L,R,dp[80][2][80][2],vis[80][2][80][2];
int d[80];
long long dfs(int dep,int f,int p,int x) {
if(dep < 0) return (p%2!=x%2);
if(f && vis[dep][f][p][x]) return dp[dep][f][p][x];
if(f) {
long long& ret = dp[dep][f][p][x];
vis[dep][f][p][x] = 1;
for(int i=0;i<=9;++i) {
if(x == -1) {
if(i == 0)  ret += dfs(dep-1,f,1,-1);
else ret += dfs(dep-1,f,1,i%2);
}
else {
if(i%2 == x) {
ret += dfs(dep-1,f,p+1,i%2);
}else {
if(p%2 == x) continue;
ret += dfs(dep-1,f,1,i%2);
}
}
}
return ret;

} else {
LL ret = 0;
for(int i=0;i<=d[dep];++i) {
if(x == -1) {
if(i == 0)  ret += dfs(dep-1,i<d[dep],1,-1);
else ret += dfs(dep-1,i<d[dep],1,i%2);
}
else {
if(i%2 == x) {
ret += dfs(dep-1,i<d[dep],p+1,i%2);
}else {
if(p%2 == x) continue;
ret += dfs(dep-1,i<d[dep],1,i%2);
}
}
}
return ret;
}
}
long long solve(long long x)
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
int len = 0;
while(x){
d[len++] = x%10;
x/=10;
}
return dfs(len-1,0,0,-1);
}
int main() {
int T,cas = 1;
scanf("%d",&T);
while(T--) {
scanf("%I64d%I64d",&L,&R);
printf("Case #%d: %I64d\n",cas++,solve(R) - solve(L-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: