题意:

求A-B之间有多少个数,满足没一个数的每个相邻数位的差的绝对值大于等于2

题解:

数位dp

看到了数位差就想到了

f[i][j]表示i位,开头为j

然后转移

最后用前缀和计数

代码:

#include<bits/stdc++.h>
const int inf=1e9;
typedef long long ll;
using namespace std;
int f[15][15],base[15],A,B;
void ini()
{
    base[1]=1;
    for (int i=2;i<=10;i++)base[i]=base[i-1]*10;
    scanf("%d%d",&A,&B);
    for (int i=0;i<=9;i++)f[1][i]=1;
    for (int i=2;i<=10;i++)
     for (int j=0;j<=9;j++)
      for (int k=0;k<=9;k++)
       if (abs(j-k)>=2)f[i][j]+=f[i-1][k];
}
int cnt(int n)
{
    if (!n)return 0;
    int tmp=0,w=10;
    while (base[w]>n)w--;
    for (int i=1;i<w;i++)
     for (int j=1;j<=9;j++)tmp+=f[i][j];
    int cur=n/base[w];
    for (int i=1;i<cur;i++)tmp+=f[w][i];
    n%=base[w];
    int pre=cur;
    for (int i=w-1;i;i--)
     {
        cur=n/base[i];
        if (i!=1)
          {
            for (int j=0;j<cur;j++)
             if (abs(pre-j)>=2)tmp+=f[i][j];
         }
        else 
         {
            for (int j=0;j<=cur;j++)
             if (abs(pre-j)>=2)tmp+=f[i][j];
         }
        if (abs(cur-pre)<2)break;
        pre=cur;
        n%=base[i];
     }
    return tmp;
}
int main()
{
    ini();
    printf("%d",cnt(B)-cnt(A-1));
    return 0;
}

 

posted on 2018-02-13 11:52  宣毅鸣  阅读(...)  评论(... 编辑 收藏