Y - odd-even number
题意:
一个数,每连续的奇数位以及连续的偶数位为一段,要求每一个奇数段(连续奇数组成的段)要有偶数个奇数,每一个偶数段(连续偶数组成的段)要有奇数个偶数,求区间[L,R]有多少个满足条件的。
思路:
dp[i][j] i代表位置,j代表状态,此题目中总共有五个状态,0代表前导零,1代表奇数为奇数个,2代表奇数为偶数,3代表偶数为奇数,4代表偶数为偶数个,总共五个状态,一一列举出来,注意limit位置不同,结果奴不一样
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
using namespace std;
typedef long long LL;
int a[25];
LL dp[25][5];
LL dfs(int pos, int limit, int sta){
if (pos < 1){
if (sta == 2 || sta == 3)
return 1;
else
return 0;
}
if (!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
int up = limit?a[pos]:9;
LL ans = 0;
for (int i = 0; i <= up; i++){
if (!sta){
if (!i){
ans += dfs(pos - 1, 0, 0);
}
else if (i & 1){
ans += dfs(pos - 1, limit&&i == up, 1);
}
else{
ans += dfs(pos - 1, limit&&i == up, 3);
}
}
else{
if (sta == 1){
if (i & 1){
ans += dfs(pos - 1, limit&&i == up, 2);
}
}
else if (sta == 2){
if (i & 1){
ans += dfs(pos - 1, limit&&i == up, 1);
}
else{
ans += dfs(pos - 1, limit&&i == up, 3);
}
}
else if (sta == 3){
if (i & 1){
ans += dfs(pos - 1, limit&&i == up, 1);
}
else{
ans += dfs(pos - 1, limit&&i == up, 4);
}
}
else{
if (!(i & 1)){
ans += dfs(pos - 1, limit&&i == up, 3);
}
}
}
}
dp[pos][sta] = ans;
return ans;
}
LL cal(LL x){
memset(dp, -1, sizeof(dp));
int len = 0;
while (x){
a[++len] = x % 10;
x /= 10;
}
return dfs(len, 1, 0);
}
int main(){
int t;
scanf("%d", &t);
for (int cas = 1; cas <= t; cas++){
LL l, r;
scanf("%lld%lld", &l, &r);
printf("Case #%d: %lld\n", cas, cal(r) - cal(l - 1));
}
}