-
X - 1024
- HDU - 5898
- 题意:在给定区间内找到符合固定的数字的个数(一段连续的奇数个数为偶数, 一段连续的偶数个数为奇数)
-
思路:数位dp[数位][到此前面连续的奇数个数][到此前面连续的偶数个数]
- i为奇数时,1.新开始一段奇数那么前面的偶数个数得是奇数个,2或者延续前面的奇数那么f1不为0,3或者前导0情况
- i为偶数数,1.新开始一段偶数那么前面的奇数个数得是偶数个,2或者延续前面的偶数那么f2不为0,3.或者前导0情况
-
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 22 int a[maxn],cas,t; ll st,ed,dp[maxn][maxn][maxn]; ll dfs(int pos,int f1,int f2,bool limit) { if(pos==0)return (!f1||!(f1&1))&&(!(f2)||(f2&1)); if(!limit&&dp[pos][f1][f2]!=-1)return dp[pos][f1][f2]; int up=limit?a[pos]:9; ll res=0; for(int i=0; i<=up; i++) { if(!(f1||f2||i))res+=dfs(pos-1,0,0,limit&&i==up);//全部为0 else if((i&1)&&((f1||f2&1)||(f1==0&&f2==0)))res+=dfs(pos-1,f1+1,0,limit&&i==up); //i为奇数时,可以是,1.新开始一段奇数那么前面的偶数个数得是奇数个,2或者延续前面的奇数那么f1不为0,3或者前导0情况 else if(!(i&1)&&((f2||!(f1&1)||(f1==0&&f2==0))))res+=dfs(pos-1,0,f2+1,limit&&i==up); //i为偶数数时,可以是,1.新开始一段偶数那么前面的奇数数个数得是偶数个,2或者延续前面的偶数数那么f2不为0,3.或者前导0情况 } if(!limit)dp[pos][f1][f2]=res; return res; } ll solve(ll x) { int pos=0; while(x) { a[++pos]=x%10; x/=10; } return dfs(pos,0,0,1); } int main() { scanf("%d",&t); memset(dp,-1,sizeof(dp)); while(t--) { scanf("%lld%lld",&st,&ed); printf("Case #%d: %lld\n",++cas,solve(ed)-solve(st-1)); } return 0; }
X - 1024 HDU - 5898 -数位DP
最新推荐文章于 2022-04-05 09:12:07 发布
本文介绍了一种使用数位动态规划(数位DP)的方法,来解决在一个给定区间内寻找特定模式的数字个数问题。具体来说,目标是在连续的奇数个数为偶数,连续的偶数个数为奇数的条件下,找到符合条件的数字数量。文章通过详细的代码解释了如何构建状态转移方程,以及如何利用递归和记忆化搜索来高效求解。
9298





