USEST OJ 1307 - windy数 数位DP

                题意:

                         windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。

                         windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

                题解:

                         典型的数位DP...用dp[x][y]代表长度为x的数..首字母为y的个数..值得注意处理的是第一个数..因为虽然看似第一个数前面还有个0约束..实际上是没有的...还有就是注意这个数本身就是非windy数时..立马跳出统计...并且统计的个数减一..


Program:

#include<iostream>    
#include<algorithm>    
#include<stdio.h>    
#include<string.h>  
#include<time.h> 
#include<map> 
#include<math.h>    
#include<queue>    
#define MAXN 6050 
#define MAXM 800005 
#define oo 1<<29
#define ll long long    
using namespace std; 
int dp[12][11]; 
void PreWork()
{
      int t,x,i,j;
      memset(dp,0,sizeof(dp));
      for (i=0;i<=9;i++) dp[1][i]=1; 
      dp[1][10]=10;
      for (t=2;t<=10;t++)  
      {
            for (x=0;x<=9;x++) 
               for (i=0;i<=9;i++)
                 if (abs(x-i)>=2)
                   dp[t][x]+=dp[t-1][i];   
            dp[t][10]=dp[t-1][10];
            for (x=1;x<=9;x++) dp[t][10]+=dp[t][x];
      } 
}  
char s[12];
int count(int x)
{
      int ans=0,p,i,len,pre=100;
      sprintf(s+1,"%d",x),len=strlen(s+1);
      for (p=len;p>=1;p--)
      { 
              if (p==len) i=1;
                     else i=0;
              for (;i<s[len-p+1]-'0';i++) 
                 if (abs(i-pre)>=2)
                    ans+=dp[p][i];
              if (abs(s[len-p+1]-'0'-pre)<2) break;
              pre=s[len-p+1]-'0';  
      }  
      ans+=dp[len-1][10];
      if (p) ans--; 
      return ans;
}
int main()   
{        
      int A,B;   
      PreWork();     
      while (~scanf("%d%d",&A,&B))  
         printf("%d\n",count(B)-count(A-1));
      return 0;  
}  


你可能感兴趣的:(USEST OJ 1307 - windy数 数位DP)