HDU5890 Eighty seven (数位DP)

来源:互联网 发布:阿里云备案登录 编辑:程序博客网 时间:2024/05/14 04:07

连着打了几场的区域赛网络赛,虽然都打到了名额…但是感觉状态不好啊…明明会的题目,总是各种wa…..

题意:给出一个区间[l, r],问其中数位中连续的奇数长度为偶数并且连续的偶数长度为奇数的个数。(1<=L<=R<= 9*10^18)

思路:就是一个数位DP,但是很久没有敲了,看以前的代码找感觉….各种小细节的处理各种麻烦…比如前导零…

#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;long long dp[20][20][2];long long cal(long long s){    long long i,j,k,ans,siz,len1,len2,sign;    vector<long long> G;    while(s){        G.push_back(s%10);        s/=10;    }    siz=G.size()-1;    ans=sign=0;    len1=len2=0;    for(i=siz;i>=0;i--){        for(j=0;j<G[i];j++){            if(i==siz&&j>0)            ans+=dp[i+1][j][1];            else{                               //根据之前的状态和当前位进行相加                if(j%2){                    if(sign==2&&len2%2==1)                    ans+=dp[i+1][j][1];                    else if(sign==1&&len1%2==1)                    ans+=dp[i+1][j][0];                    else if(sign==1&&len1%2==0)                    ans+=dp[i+1][j][1];                }                else{                           //偶数的时候要特别注意                    if(sign==1&&len1%2==0)                    ans+=dp[i+1][j][1];                    else if(sign==2&&len2%2==1)                    ans+=dp[i+1][j][0];                    else if(sign==2&&len2%2==0)                    ans+=dp[i+1][j][1];                }            }        }        if(G[i]%2){                             //判断之前的状态            if(sign==2&&len2%2==0)            break;            if(sign==2)            len1=1;            else            len1++;            sign=1;        }        else{            if(sign==1&&len1%2==1)            break;            if(sign==1)            len2=1;            else            len2++;            sign=2;        }    }    for(i=siz;i>=1;i--)    for(j=1;j<=9;j++)    ans+=dp[i][j][1];    return ans;}int main(){                                     //dp[i][j][1]表示i为数首位是j的,满足条件的种数    long long t,n,i,j,k,l,r,cas;                //dp[i][j][0]表示i为数首位是j的,不满足条件的种数    scanf("%I64d",&t);                          //主要是根据下面的博客    for(cas=1;cas<=t;cas++){                           scanf("%I64d%I64d",&l,&r);        memset(dp,0,sizeof(dp));        for(i=0;i<10;i++){            if(i%2)            dp[1][i][0]=1;            else            dp[1][i][1]=1;        }        for(i=2;i<=20;i++){            for(j=0;j<10;j++){                for(k=0;k<10;k++){              //根据相邻两位的关系进行预处理                    if((j%2)==(k%2)){                        dp[i][j][1]+=dp[i-1][k][0];                        dp[i][j][0]+=dp[i-1][k][1];                    }                    else if(j%2)                    dp[i][j][0]+=dp[i-1][k][1];                    else                    dp[i][j][1]+=dp[i-1][k][1];                }            }        }        printf("Case #%I64d: %I64d\n",cas,cal(r+1)-cal(l));    }    return 0;}
0 0
原创粉丝点击