数位dp HDU - 5898 odd-even number
Posted -zzz-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数位dp HDU - 5898 odd-even number相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=5898
题意:求两个数中间的满足连续位是奇数的长度是偶数,连续位上是偶数的长度位奇数的数量。
分析:就是数位dp基本写法,dfs 的参数多加了个 a 表示连续位数的长度,flag表示上一位是否为奇数。 这里当奇偶改变时,a 就要变成1 ,并且可以用 a=0 来表示区分是前导0 。然后 记忆化搜索的过程中 ,用continue 表示不满足条件,暂时满足才往下接着搜索。
然后!! &运算的优先程度比 ==运算小啊! 位运算还是多加括号吧
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const ll maxn = 9e18; int n; int dig[20]; ll dp[20][20][2][2]; int Max; ll dfs(int pos,int a,int up,int flag) //flag:上一位是否为奇数 // printf("yes\n"); if(pos<0) return 1; if (!up && dp[pos][a][up][flag] != -1) return dp[pos][a][up][flag]; ll res=0; for (int i = 0; i <= 9; i++) // if(pos == Max && i==0) continue; if (up && (i > dig[pos])) break; int b; if(a==0&&i!=0) b=1; else if(a==0&&i==0) b=0; else if( pos == Max) b=1; else b= ((i&1)==flag)?a+1:1; if(a!=0&&b==1) if(( flag&1 ) == (a&1) ) continue; // if(b==0) b++; if(pos==0 && ((i&1) == (b&1))) continue; // printf("pos=%d i=%d \n", pos,i); // if(pos==0&&!(i&1) == (b&1)) printf("yes\n"); res += dfs( pos-1, b,up && i == dig[pos],i&1 ); // printf("res=%d\n", res); if(!up) dp[pos][a][up][flag]=res; return res; ll sol(ll x) if(x==0) return 0; if(x<0) return 0; int i=0; while(x) dig[i++] = x%10; x/=10; Max=i-1; return dfs(Max, 0, 1, 0 ); int main() int T; scanf("%d",&T); ll x,y; int kase=1; memset(dp,-1,sizeof(dp)); while(T--) scanf("%lld%lld",&x,&y); printf("Case #%d: %lld\n", kase++,sol(y)-sol(x-1));
以上是关于数位dp HDU - 5898 odd-even number的主要内容,如果未能解决你的问题,请参考以下文章
数位dp HDU - 5898 odd-even number