首页 > 代码库 > HDU 5898 (数位DP)
HDU 5898 (数位DP)
HDU 5898 odd-even number
题意:如果一个数连续的奇数之和为偶数,连续的偶数之和为奇数则满足条件,问某一区间内满足条件的数字的个数。
思路:数位DP,dp[i][j][k][u]表示计算到底i位,是否为临界值,上一位是奇还是偶,连续奇或偶有u个,在dfs是多记录一下该数前面是不是全为0以及该数是不是已近不满足条件。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>using namespace std;typedef long long LL;vector<int> v;LL l,r;LL dp[25][2][2][25];//第i位,是否为临界值,上一位是奇还是偶,连续或偶的个数LL dfs(int pos,int pan,int status,int num,int ok1,int ok2){ if(ok1) return 0; if(pos<0){ if(ok2==0) return 0; if(status==1&&num%2==0) return 1; if(status==0&&num%2==1) return 1; return 0; } if(dp[pos][pan][status][num]!=-1) return dp[pos][pan][status][num]; LL cnt=0; int k=pan?v[pos]:9; for(int i=0;i<=k;i++){ int nowpan,nowstatus,nownum; int nowok1=0,nowok2=0; nowpan=(pan&&(i==k))?1:0; if(i==0){//该位为0 if(ok2==0){//前面全是0 nowok2=0; nownum=0; nowstatus=0; } else{//前面并非全是0 nowok2=1; nowstatus=0; if(status==1){//前一个是奇,这个发生改变 nownum=1; if(num%2==1) nowok1=1; } else{//前一个是偶,这个继续 nownum=num+1; } } } else if(i%2==1){//非0且为奇 nowok2=1; nowstatus=1; if(status==1){//前面为奇,继续 nownum=num+1; } else{//前面为偶,发生改变 nownum=1; if(num%2==0&&num!=0) nowok1=1; } } else{//非0且为偶 nowok2=1; nowstatus=0; if(status==1){//前面为奇,发生改变 nownum=1; if(num%2==1&&num!=0) nowok1=1; } else{//前面为偶,继续 nownum=num+1; } } //printf("%d %d %d %d %d\n",nowpan,nowstatus,nownum,nowok1,nowok2); cnt+=dfs(pos-1,nowpan,nowstatus,nownum,nowok1,nowok2); } return dp[pos][pan][status][num]=cnt;}int main(){ int t; cin>>t; int T=t; while(t--){ cin>>l>>r; l--; v.clear(); memset(dp,-1,sizeof(dp)); while(l){ v.push_back(l%10); l/=10; } int len=v.size()-1; LL a=dfs(len,1,1,0,0,0); v.clear(); memset(dp,-1,sizeof(dp)); while(r){ v.push_back(r%10); r/=10; } len=v.size()-1; LL b=dfs(len,1,1,0,0,0); printf("Case #%d: ",T-t); cout<<b-a<<endl; } return 0;}
HDU 5898 (数位DP)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。