数位dp无前导零

题目链接:http://    www.lydsy.com/JudgeOnline/problem.php?id=1026

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;


int A[12];


int f[12][10];


//f[i][j]代表长度为i,最高位为j的windy数个数
void init()
{
   memset(f,0,sizeof(f));
   for(int i=0;i<10;i++) f[1][i] = 1;
   for(int i=2;i<=10;i++)
   {
      for(int j=0;j<10;j++)
      {
         for(int k=0;k<10;k++)
         {
            if(abs(j-k)>1) f[i][j] += f[i-1][k];
         }
      }
   }
}
//(0,a)范围内的windy数个数
int calc(int a)
{
   int m = 0;
   while(a)
   {
      A[m++] = a%10;
      a/=10;
   }
   int ans = 0;
   //先处理长度小于m的windy数的个数
   for(int i=1;i<m;i++)
   {
      //题目要求不含前导0
      for(int j=1;j<10;j++)
      {
         ans += f[i][j];
      }
   }
   //长度等于m且最高位和原数不同且小于原数的windy数
   for(int j=1;j<A[m-1];j++) ans += f[m][j];
   //依次循环将最高位 变为和原数相同
   for(int i=m-1;i>=1;i--)
   {
      for(int j=0;j<A[i-1];j++)
      {
         if(abs(j-A[i]) > 1) ans += f[i][j];
      }
      if(abs(A[i] - A[i-1])<=1) break;
   }
   return ans;
}




int main()
{
   #ifndef ONLINE_JUDGE
      freopen("in.txt","r",stdin);
   #endif
   int a,b;
   init();
   while(scanf(" %d %d",&a,&b)!=EOF)
   {
      int ans = calc(b+1) - calc(a);
      printf("%d ",ans );
   }
   return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410770.html