题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的。问[L , R]的好数个数。
题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的值的奇偶性和长度奇偶性即可.
#include <iostream> #include <vector> #include <string.h> #include <stdio.h> #include <queue> using namespace std; long long dp[25][2][25]; int bit[25]; long long dfs(int pos,int preTy,int prelen,bool flag) { //flag为true的话表示当前位触顶了 if(pos==-1) { if(prelen%2 != preTy) return 1; else return 0; } if(!flag && dp[pos][preTy][prelen]!=-1) return dp[pos][preTy][prelen]; int e = flag?bit[pos]:9; long long ans=0; for(int i=0;i<=e;i++) { if(prelen==0&&i==0) { ans += dfs(pos-1,1,0,flag&&i==e); //ans += dfs(pos-1,i%2,preTy==0?prelen+1:1,flag&&i==e); } else if(i%2==0) { if(preTy==1&&prelen%2==1) continue; ans += dfs(pos-1,0,preTy==0?prelen+1:1,flag&&i==e); } else { if(preTy==0&&prelen%2==0) continue; ans += dfs(pos-1,1,preTy==1?prelen+1:1,flag&&i==e); } } //printf("%d %d %d %d %d ",pos,preTy,prelen,flag,ans); if(!flag) return dp[pos][preTy][prelen]=ans; return ans; } long long solve(long long n) { int pos=0; while(n) { bit[pos++] = n%10; n/=10; } memset(dp,-1,sizeof(dp)); return dfs(pos-1,1,0,true); } int main() { int T; long long l,r; cin>>T; int kase=1; while(T--) { cin>>l>>r; printf("Case #%d: ",kase++); cout<<solve(r)-solve(l-1)<<endl; //cout<<solve(r)<<endl; } }