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


    题目背景

    windy 定义了一种 windy 数。

    题目描述

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

    输入格式

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

    输出格式

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

    输入输出样例

    输入 #1复制

    1 10
    

    输出 #1复制

    9
    

    输入 #2复制

    25 50
    

    输出 #2复制

    20
    

    参考https://www.luogu.com.cn/blog/HONOUR/solution-p2657

    从0开始数位dp。

    #include <bits/stdc++.h>
    using namespace std;
    int a, b, num[33], len;
    int dp[33][33][2][2];
    int dfs(int len, int last, int flag, int zero) {//参数为从高到低当前处理到第几位 范围是1到len last是上一位的数 flag表示之前的部分是否紧贴边界 zero表示是否有前导0
    	if(len == 0) return 1;//实际上可以在下面代码中特判 比如len == 1且满足条件 则直接ans += 1
    	if(dp[len][last][flag][zero] != -1) return dp[len][last][flag][zero];
    	int ans = 0;
    	for(int i = 0; i <= 9; i++) {
    		if((abs(i - last) >= 2 || zero) && ((flag && i <= num[len]) || !flag)) {//当前面全为0的时候这一位不用管相差多少
    			ans += dfs(len - 1, i, flag && (i == num[len]), zero && (i == 0));
    		}
    	}
    	return (dp[len][last][flag][zero] = ans);
    }
    int calc(int x) {
    	memset(num, 0, sizeof(num));
    	len = 1;
    	while(x) {
    		int now = x % 10;
    		x /= 10;
    		num[len] = now;
    		len++;
    	}
    	for(int i = 0; i < 32; i++) {
    		for(int j = 0; j < 32; j++) {
    			for(int k = 0; k < 2; k++) {
    				for(int w = 0; w < 2; w++) {
    					dp[i][j][k][w] = -1;
    				}
    			}
    		}
    	}
    	return dfs(len, 11, 1, 1);
    }
    int main() {
    	cin >> a >> b;
    	cout << calc(b) - calc(a - 1);
    	return 0;
    }
    
  • 相关阅读:
    maven更新远程仓库速度太慢解决方法
    maven安装配置
    myeclipse中配置maven
    java数组的常用函数
    在数组中插入元素
    MySQL的表使用
    MySQL的数据库与表格创建
    节点的添加与删除
    html常用的综合体
    标签的类添加与删除
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/14714629.html
Copyright © 2020-2023  润新知