zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    洛谷P3376 【模板】网络最大流
    bzoj 4598: [Sdoi2016]模式字符串
    JAVA类(下)
    2019DDCTF部分Writeup
    Atom配置(VIM党) · iuunhao
    Tips
    rsync auth failed on module xxx
    基于mykernel完成时间片轮询多道进程的简单内核
    机器学习技法笔记(2)-Linear SVM
    css之制作三角形
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/14714629.html
Copyright © 2011-2022 走看看