fzu 2109 Mountain Number 数位DP 记忆化搜索

来源:互联网 发布:淘宝上正品球鞋店 编辑:程序博客网 时间:2024/05/18 15:55

做法:按位暴力DFS吧...

这里很明显没有考虑当前数字是否是首位,其实不需要啊,因为这种情况发生的时候肯定是那种比边界数少一位的数字。也就是说如果求1234 那么这里要考虑的是 0 ---999的

数字中的mountain, 没有考虑首位的后果是moutain的形态不同,可是很容易证明,规定位数的数字只有两种moutain,而这种两种moutain在 0---999中的个数相同。

#include <iostream>#include <cstdio>#include <cstring>#define LL long longconst int LMT=11;using namespace std;LL dp[LMT][LMT][LMT];int sec[LMT];LL dfs(int pre,int pos,int len,bool tag){    if(dp[pre][pos][len]!=-1&&(!tag||pos==len))return dp[pre][pos][len];    LL res=0;    int end=tag?sec[pos]:9;    if(pos&1)    {        for(int j=end;j>=pre;j--)        res+=dfs(j,pos+1,len,tag&&j==end);    }    else    {        for(int j=min(end,pre);j>=0;j--)        res+=dfs(j,pos+1,len,tag&&j==end);    }    if(!tag)dp[pre][pos][len]=res;    return res;}int work(LL x){    int num[LMT],res=0;    do    {        num[res]=x%10;        res++;    }    while(x/=10);    for(int i=0,j=res-1;j>=0;j--,i++)    sec[i]=num[j];    return res;}int main(void){    int T;    scanf("%d",&T);    memset(dp,-1,sizeof(dp));    for(int i=0;i<LMT;i++)     for(int j=0;j<LMT;j++)     dp[i][j][j]=1;    while(T--)    {        LL a,b,x,y;        scanf("%I64d%I64d",&a,&b);        x=dfs(9,0,work(a-1),1);        y=dfs(9,0,work(b),1);        printf("%I64d\n",y-x);    }    return 0;}


原创粉丝点击