UESTC 250 windy数 (数位DP)

http://acm.uestc.edu.cn/#/problem/show/250
题意:中文题…

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<vector>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm> 
using namespace std;
typedef long long LL;
#define maxn 1005
#define f(x) (x*1.0)
#define inf 0x3f3f3f3f
#define maxm maxn*maxn
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
#define lowbit(x) (x&(-x))
#define cheak(i) printf("%d ",i)
#define lson(x) (splay[x].son[0])
#define rson(x) (splay[x].son[1])
#define rfor(i,a,b) for(i=a;i<=b;++i)
#define lfor(i,a,b) for(i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define mec(a,b) memcpy(a,b,sizeof(b))
int dp[15][10];
void init()
{
    mem(dp,0);
    int i,j,k;
    rfor(i,0,9) dp[1][i]=1;
    rfor(i,2,12)
     rfor(j,0,9)
     {
        rfor(k,j+2,9) dp[i][j]+=dp[i-1][k];
        rfor(k,0,j-2) dp[i][j]+=dp[i-1][k];
    }
}
int A[15];
//下边以X=654321举例子 
int solve(int x)
{
    int len=0,ans=0,i,j;
    while(x)
    {
        A[++len]=x%10;
        x/=10;
    }
    A[len+1]=0;
    rfor(i,1,A[len]-1) ans+=dp[len][i];
    //统计100000~599999中的windy数
    rfor(i,1,len-1)
     rfor(j,1,9) ans+=dp[i][j];
    //printf("%d\n",ans);
    //统计1~99999中的windy数 
    lfor(i,len-1,1)//统计以6开头并且小于654321的windy数 
    {
        rfor(j,0,A[i]-1)
        if(abs(j-A[i+1])>=2) ans+=dp[i][j];
        if(abs(A[i+1]-A[i])<2) break;
     }
    return ans;
}
int main()
{
    init();
    int i,l,r;
    //rfor(i,1,9) printf("%d--",dp[1][i]);
    while(~scanf("%d%d",&l,&r))
    {
        printf("%d\n",solve(r+1)-solve(l));
    }
    return 0;
}

你可能感兴趣的:(数位dp)