FZU 2109 Mountain Number

http://acm.fzu.edu.cn/problem.php?pid=2109

 

题意:找出区间[l,r]内满足奇数位的数字大于相邻偶数位数字的个数。

典型的数位dp了,记录一下当前位是奇数位还是偶数位。

状态设计为到当前位为(奇数还是偶数的条件下上一位数字为x的)满足条件的 个数。

 

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 20;
int dp[MAX][MAX][2];
int digit[MAX];
int dfs(int pos,int pre,bool c,bool limit,bool check)
{
    if(!pos)
    {
        if(!check) return 1;
        else return 0;
    }
    if(check) return 0;
    if(!limit&&~dp[pos][pre][c]&&!check) return dp[pos][pre][c];
    int end=limit?digit[pos]:9int ans=0;
    for(int i=0;i<=end;i++)
    {
        if(c&&pre<=i) ans+=dfs(pos-1,i,c^1,limit&&(end==i),check);
        else if(!c&&pre>=i) ans+=dfs(pos-1,i,c^1,limit&&(end==i),check);
        else ans+=dfs(pos-1,i,c^1,limit&&(end==i),check||1);
    }
    if(!limit&&!check) dp[pos][pre][c]=ans;
    return ans;
}
int solve(int n)
{
    int cur=0;
    while(n)
    {
        digit[++cur]=n%10;
        n/=10;
    }
    return dfs(cur,9,false,true,false);
}
int main()
{
    int cas,L,R;
    scanf("%d",&cas);
    memset(dp,-1,sizeof(dp));
    while(cas--)
    {
        scanf("%d %d",&L,&R);
        printf("%d\n",solve(R)-solve(L-1));
    }
}
View Code
posted @ 2014-07-03 10:58  acvc  阅读(326)  评论(0编辑  收藏  举报