• P2657 [SCOI2009] windy 数(数位DP)


    题目背景

    windy 定义了一种 windy 数。

    题目描述

    不含前导零且相邻两个数字之差至少为 22 的正整数被称为 windy 数。windy 想知道,在 aa 和 bb 之间,包括 aa 和 bb ,总共有多少个 windy 数?

    输入格式

    输入只有一行两个整数,分别表示 aa 和 bb

    输出格式

    输出一行一个整数表示答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    typedef long long ll;
    ll f[20][20];//f(i,j)表示搜到第i位,前一位是j的合法方案数
    int a[20],len;
    ll L,R;
    ll dfs (int pos,int pre,int st,int limit) {
    	//pos表示当前位置
    	//pre表示前一位数
    	//st表示前面是否全为0
    	//limit表示最高位限制
    	
    	if (pos>len) return 1;//dfs终点 
    	if (!limit&&f[pos][pre]!=-1) return f[pos][pre];
    	//没有最高位限制,并且已经搜过了
    	ll ans=0;
    	ll k=limit?a[len-pos+1]:9;//当前位最大数字
    	for (int i=0;i<=k;i++){
    		//从0枚举最大数字 
    		if (abs(i-pre)<2) continue;
    		//不符合题意,继续
    		if (st&&i==0) {
    			//如果前面全为0,下一位随意
    			ans+=dfs(pos+1,-2,1,limit&&i==k);
    			//如果有前导0,下一位随意 
    		} 
    		else {
    			//如果没有前导0,继续按部就班的搜
    			ans+=dfs(pos+1,i,0,limit&&i==k); 
    		}
    	} 
    	if (!limit&&!st) {
    		//没有最高位限制且没有前导0时记录结果 
    		f[pos][pre]=ans;
    	}
    	return ans;
    } 
    ll solve (ll x) {
    	len=0;
    	while (x) a[++len]=x%10,x/=10;
    	memset(f,-1,sizeof(f));
    	return dfs(1,-2,1,1); 
    }
    int main () {
    	cin>>L>>R;
    	cout<<solve(R)-solve(L-1);
    }
  • 相关阅读:
    docker tar 镜像 容器相互转换
    JavaScript执行上下文
    JavaScript 作用域
    原型与原型链
    使用Navicat for Oracle新建表空间、用户及权限赋予
    PL/SQL Developer使用教程(中文)
    一步一步使用bootstrap开发一个博客模板
    How to create a simple blog using ASP.NET MVC
    一个有意思的编程网站
    一个很好的java编程国外网站
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14590342.html
Copyright © 2020-2023  润新知