您的位置:首页 > 大数据 > 人工智能

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

2013-02-28 21:39 489 查看
做法:按位暴力DFS吧...

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

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

#include <iostream>
#include <cstdio>
#include <cstring>
#define LL long long
const 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: