-
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
最新推荐文章于 2020-09-22 19:09:02 发布