描述:
odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 375 Accepted Submission(s): 207
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
Source
Recommend
题意:
连续奇数长度为偶数,连续的偶数的长度是奇数,求有多少种
思路:
dp[i][j][k]的定义是i位数,首位为j,k=1时表示满足条件,k=0的时候表示可能转化为满足条件的数,处理出来之后数位DP就可以了
主循环当中不计算前导0,而是另外使用一个循环来计算含有前导0的情况下满足条件的数的数量
代码:
#include<bits/stdc++.h>
#define ll __int64
using namespace std;
ll dp[20][10][2];
ll l,r;
int kase=1;
void init(){
memset(dp, 0, sizeof(dp));
for(int i=0; i<10; i++){
if((i&1)==0)dp[1][i][1]=1;
else dp[1][i][0]=1;
}
for(int i=2; i<=20; i++){
for(int j=0; j<10; j++){
for(int k=0; k<10; k++){
if((j&1)==(k&1)){
dp[i][j][1]+=dp[i-1][k][0];
dp[i][j][0]+=dp[i-1][k][1];
}
else if(j&1)dp[i][j][0]+=dp[i-1][k][1];
else dp[i][j][1]+=dp[i-1][k][1];
}
}
}
}
ll solve(ll cur){
int a[105],bit=0;
ll tmp=cur,ans=0;
int num=0;
while(tmp){
a[++bit]=tmp%10;
tmp/=10;
}
a[bit+1]=0;
for(int i=bit; i>=1; i--){
//printf("%d\n",num);
for(int j=0; j<a[i]; j++){
if(bit==i && j>0)ans+=dp[i][j][1];
else if(i<bit){
if(j&1){
if(a[i+1]%2==0 && (num&1))
ans+=dp[i][j][1];
else if(a[i+1]%2==1 && (num&1))
ans+=dp[i][j][0];
else if(a[i+1]%2==1 && !(num&1))
ans+=dp[i][j][1];
}
else{
if((a[i+1]%2==1)&& num%2==0)
ans+=dp[i][j][1];
else if(a[i+1]%2==0 && num%2==0)
ans+=dp[i][j][1];
else if((a[i+1]%2==0)&&(num%2==1))
ans+=dp[i][j][0];
}
}
}
if(i==bit){
num=1;
continue;
}
if((a[i]&1)!=(a[i+1]&1)){
if((a[i+1]&1)&&(num&1))break;
if(!(a[i+1]&1)&&!(num&1))break;
num=1;
}
else num++;
}
//solve the leading zero case
for(int i=bit-1; i>=1; i--){
for(int j=1; j<=9; j++)
ans+=dp[i][j][1];
}
return ans;
}
int main(){
// #ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
// #endif
int t;
scanf("%d",&t);
init();
while(t--){
scanf("%I64d%I64d",&l,&r);
printf("Case #%d: %I64d\n",kase++,solve(r+1)-solve(l));
}
return 0;
}

本文详细解析了HDU5898题目中的奇偶数问题,通过动态规划的方法解决了求解两个给定数值范围内满足特定奇偶条件的数的数量问题。

被折叠的 条评论
为什么被折叠?



