BZOJ 1026

题目大意:

   windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?(来源于:黑暗爆炸oj)

解题思路:
  • 数位dp,加个前导0的判断条件以及设 d p [ i ] [ s t a ] dp[i][sta] dp[i][sta]代表第 i + 1 i+1 i+1位选 s t a sta sta的总个数
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e2;
ll dp[maxn][10], digit[maxn], A, B;
ll read() {
	ll X = 0, p = 1; char c = getchar();
	for(; c > '9' || c < '0'; c = getchar()) if (c == '-') p = -1;
	for(; c <= '9' && c >= '0'; c = getchar()) X = X * 10 + c - '0';
	return X * p; 
}
ll dfs(int pos, int sta, bool limit, bool zero) {
	if (!pos) return 1;
	if (!limit && !zero && dp[pos][sta] != -1) return dp[pos][sta];
	int up = limit ? digit[pos] : 9;
	ll ans = 0;
	for (int i = 0; i <= up; i++) {
		if (abs(i - sta) < 2 && !zero) continue;
		ans += dfs(pos - 1, i, limit && i == digit[pos], zero && i == 0);
	}
	if (!limit && !zero) dp[pos][sta] = ans;
	return ans;
}
ll solve(ll x) {
	int cnt = 0;
	memset(dp, -1, sizeof(dp));
	while (x) digit[++cnt] = x % 10, x /= 10;
	return dfs(cnt, 0, true, true);
}
int main() {
	A = read(), B = read();
	//cout << solve(B) << endl;
	printf("%lld\n", solve(B) - solve(A - 1));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值