Preface
To practice DP more, we need to master the various types of DP proficiently...............................................
subject
Windy defines a kind of windy number.
A positive integer that does not contain leading zeros and the difference between two adjacent numbers is at least 2 is called a windy number.
Winy wants to know how many Windies are there between A and B, including A and B?
Input
Two integers, A B.
Output
An integer representing how many windy numbers are in A~B.
Sample Input
1 10
Sample Output
9
[Data Scope]
100% data, 1 <= A <= B <= 2000000000
Analysis
There is a wide range of numbers. Violence will certainly not work.
Positive Solution: [Digital DP] Recommend classical examples [Do not 62]
(These seem to have been mentioned by Mr. Wu before, but after a long time, I forgot... Sweat.)
Thoughts come from blogs (special thanks): https://blog.csdn.net/zz_ylolita/article/details/50754618
It's very detailed. I won't go into it here.
After a while of entanglement, I decided to elaborate on the "first, second and third parts" (because it was very difficult for me to understand at that time):
Set X=7634,
Part I: The number of types of ans+=1__+2_+...+6________________
Part Two: The Number of ans+=_+_________
Part III: The number of types of ans+=7_______________
See the code, it will be better to understand.
Examination Violence Code
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll a,b,ans; bool Check(ll x) { bool flag=true; int a,tmp=-2; while(x>0) { a=x%10; x/=10; if(abs(a-tmp)<2) { flag=false; break; } tmp=a; } return flag; } int main() { scanf("%lld%lld",&a,&b); for(int i=a;i<=b;i++) if(Check(i)) ans++; printf("%lld",ans); return 0; } //Violence goes out of time.
AC code
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll dp[15][15]; ll a,b; int len,digit[15]; void Prepare() { for(int i=0;i<=9;i++) dp[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) dp[i][j]+=dp[i-1][k]; } ll Solve(ll x) { ll ret=0; int len=0; if(x==0) return 0; while(x>0) { digit[++len]=x%10; x/=10; } for(int i=1;i<=digit[len]-1;i++) ret+=dp[len][i]; for(int i=len-1;i>0;i--) for(int j=1;j<=9;j++) ret+=dp[i][j]; for(int i=len-1;i>=1;i--) { for(int j=0;j<=digit[i]-1;j++) if(abs(digit[i+1]-j)>=2) ret+=dp[i][j]; if(abs(digit[i+1]-digit[i])<2) break; } return ret; } int main() { scanf("%lld%lld",&a,&b); Prepare(); printf("%lld",Solve(b+1)-Solve(a)); return 0; }