数位DP之找等凹数字

来源:互联网 发布:淘宝店铺音乐怎么关闭 编辑:程序博客网 时间:2024/05/02 04:48

题目链接


#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <time.h>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;long long dp[20][20][10][2][2][2];int num[20];int s[20];//第 i 位,长度为 len,上一位是什么,前面是否递增过,前面是否递减过,当前是否符合回文串的性质,flag就是普通的前一位是否有限制,q是盘是否前导0long long rec(int i,int pre,int up,int down,int flag,int q,int len,int ispa){    if(i<0)        return up&&down&&ispa;    if(dp[i][len][pre][up][down][ispa]!=-1&&!flag&&!q)        return dp[i][len][pre][up][down][ispa];    long long res=0;    int o=s[i];    for(int j=0;j<10;j++)    {        num[i]=j;        if(j>o&&flag)            break;        if(q)            res+=rec(i-1,j,0,0,j<o?0:flag,q&&j==0,len-(q&&j==0),ispa);        else if(j==pre)        {            if(ispa&&i<len/2)                res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);            else                res+=rec(i-1,j,up,down,j<o?0:flag,q&&j==0,len,ispa);        }        else if(j>pre)        {            if(!down)                continue;            if(ispa&&i<len/2)                res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);            else                res+=rec(i-1,j,1,down,j<o?0:flag,q&&j==0,len,ispa);        }        else if(j<pre)        {            if(up)                continue;            if(ispa&&i<len/2)                res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,j==num[len-i-1]);            else                res+=rec(i-1,j,up,1,j<o?0:flag,q&&j==0,len,ispa);        }    }    if(!flag&&!q)        dp[i][len][pre][up][down][ispa]=res;    return res;}long long cal(long long x){    int len=0;    while(x)    {        s[len++]=x%10;        x/=10;    }    return rec(len-1,0,0,0,1,1,len,1);}int main(){    memset(dp,-1,sizeof(dp));    long long l,r;    int t;    scanf("%d",&t);    while(t--){    scanf("%lld%lld",&l,&r);    printf("%lld\n",cal(r)-cal(l-1));    }    return 0;}


未检测,不能交题,但是应该是对的#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <time.h>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;typedef long long ll;int a[20];int keep[20];int dp[20][20][20][2][2][2];ll dfs(int len,int pos,int pre,int up,int down,int limit,int flag0,int judge){    if(pos<0)        return up&&down&&judge;    if(!flag0&&!limit&&dp[len][pos][pre][up][down][judge]!=-1)        return dp[len][pos][pre][up][down][judge];    ll sum=0;    int tmp=a[pos];    for(int i=0;i<=9;i++)    {        keep[pos]=i;        if(limit&&i>tmp)            break;        if(flag0)            sum+=dfs(len-(flag0&&i==0),pos-1,i,0,0,limit&&i==tmp,flag0&&i==0,judge);        else if(i==pre)        {            if(judge&&pos<len/2)                sum+=dfs(len,pos-1,i,up,down,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);            else                sum+=dfs(len,pos-1,i,up,down,limit&&i==tmp,flag0&&i==0,judge);        }        else if(i>pre)        {            if(!down)                continue;            if(judge&&pos<len/2)                sum+=dfs(len,pos-1,i,1,down,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);            else                sum+=dfs(len,pos-1,i,1,down,limit&&i==tmp,flag0&&i==0,judge);        }        else if(i<pre)        {            if(up)                continue;            if(judge&&pos<len/2)                sum+=dfs(len,pos-1,i,up,1,limit&&i==tmp,flag0&&i==0,i==keep[len-pos-1]);            else                sum+=dfs(len,pos-1,i,up,1,limit&&i==tmp,flag0&&i==0,judge);        }    }    if(!flag0&&!limit)        dp[len][pos][pre][up][down][judge]=sum;    return sum;}ll solve(ll x){    if(x<=100)        return 0;    int pos=0;    while(x)    {        a[pos++]=x%10;        x/=10;    }    return dfs(pos,pos-1,0,0,0,1,1,1);}int main(){    memset(dp,-1,sizeof(dp));    ll l,r;    int t;    scanf("%d",&t);    while(t--)    {        scanf("%lld%lld",&l,&r);        printf("%lld\n",solve(r)-solve(l-1));    }    return 0;}



0 0
原创粉丝点击