[SCOI2009]windy数 代码 (对应数位dp入门)

Code1 (DP版)

#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
int read()
{
	int ans=0,f=1;
	char i=getchar();
	while(i<'0' || i>'9') {
		if(i=='-') f=-1;
		i=getchar();
    }
	while(i>='0' && i<='9') {
		ans=(ans<<1)+(ans<<3)+i-'0';
		i=getchar();
    }return ans*f;
}
int dp[12][10],bit[10];

void init()
{
	for(int i=0;i<=9;i++) dp[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)>=2) dp[i][j]+=dp[i-1][k];
    }
}

int solve(int x)
{
	if(x==0) return 0; int ans=0,len=0;
	memset(bit,0,sizeof(bit));
	while(x) {
		bit[++len]=x%10;
		x/=10;
    }
	for(int i=1;i<=len-1;i++)
		for(int j=1;j<=9;j++)
			ans+=dp[i][j];
	for(int i=1;i<bit[len];i++) ans+=dp[len][i];
	for(int i=len-1;i>=1;i--) {
		for(int j=0;j<bit[i];j++)
			if(abs(bit[i+1]-j)>=2) ans+=dp[i][j];
		if(abs(bit[i+1]-bit[i])<2) break;
		if(i==1) ans++;
    }return ans;
}
int main()
{
	init(); int a,b;
	in(a);in(b);
	cout<<solve(b)-solve(a-1)<<endl;
}

Code2(记忆化搜索版)

#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
int read()
{
	int ans=0,f=1;
	char i=getchar();
	while(i<'0' || i>'9') {
		if(i=='-') f=-1;
		i=getchar();
    }
	while(i>='0' && i<='9') {
		ans=(ans<<1)+(ans<<3)+i-'0';
		i=getchar();
    }return ans*f;
}
int bit[11], dp[11][10];
int dfs(int len,int pre,int f,int limit)
{
	int ans=0;
	if(!len) return 1;
	if(!limit && f && dp[len][pre]) return dp[len][pre];
	int maxn=limit?bit[len]:9;
	for(int i=0;i<=maxn;i++)
    {
		if(abs(i-pre)>=2) {
			int p=i;
			if(pre==-10 && !i) p=pre;
			ans+=dfs(len-1,p,f||i!=0,limit && i==maxn);
		}
    }
	if(!limit && f) dp[len][pre]=ans;
	return ans;
}
int solve(int a)
{
	memset(bit,0,sizeof(bit));
	int k=0;
	while(a) {
		bit[++k]=a%10;
		a/=10;
    }return dfs(k,-10,0,1);
}
int main()
{
	int a,b;
	in(a);in(b);
	cout<<solve(b)-solve(a-1)<<endl;
	return 0;
}
posted @ 2019-11-13 20:37  real_l  阅读(207)  评论(0编辑  收藏  举报