[2019- solution] Chung Memorial middle school summer tour Day9 - windy number

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;
}

 

Posted by TeNDoLLA on Fri, 04 Oct 2019 14:16:22 -0700