1026 windy數
阿新 • • 發佈:2018-12-13
給兩個數1 <= a <= b <= 2e9,求他們之間的windy數的個數
windy數定義:不含前導零且相鄰兩個數字之差至少為2的正整數被稱為windy數。
這題用數位dp來做
定義:dp[i][j]:第i位數字為j,並且滿足情況數的個數.
那麼狀態轉移方程為
dp[i][j] = ∑dp[i−1][k] (abs(k−j) >= 2)
最後用差分搞一搞,solve(b + 1) - solve(a)就是a, b之間滿足情況的個數了(solve(x)表示小於x的滿足條件的個數)
“注意一下dp細節即可”
咳咳還是說一下dp的細節:
初始化為0,不談。
dp[1][i]初始化為1,這是處理只有一位的情況
然後對於2-11位,列舉這一位的數字j,對於這個j,列舉它的前面一位數字為k,滿足abs(k - j) >= 2就更新
dp[i][j] += dp[i-1][k]
好啦,dp陣列初始化好了,對於一個數n,如何求小於它的滿足條件的數的個數呢
比如一個數是四位的
首先加上三位的所有情況,再加上第四位1-(num[4] - 1)的所有情況
以上這些情況都是能嚴格保證小於所給的數的
所以要特殊對待一下第四位就是所給的數的第四位的時候
從高位往地位遍歷,如果相差可以大於2的話就加上這個位置的答案,並且一旦碰到給出的相差就小於2,直接break
(因為你往下不能改了)
最後很容易發現所給的數本身是沒有判斷的,所以算出來的是小於這個數的答案
說的不太清楚,反正我是理解了,嘻嘻
#pragma GCC diagnostic error "-std=c++11" #include<set> #include<map> #include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<string> #include<vector> #include<cstdlib> #include<cstring> #include<iomanip> #include<iostream> #include<algorithm> #define fi first #define se second #define pb push_back #define lowbit(x) x&(-x) #define PII pair<int, int> #define all(x) x.begin(), x.end() #define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) typedef long long ll; const int inf = 0x3f3f3f3f; const int mod = (int)1e9 + 7; const int maxn = (int)1e5 + 5; using namespace std; #define int ll int dp[12][10]; int num[12]; void init(){ memset(dp, 0, sizeof(dp)); for(int i = 0; i <= 9; i++) dp[1][i] = 1; for(int i = 2; i <= 11; i++){ for(int j = 0; j <= 9; j++){ for(int k = 0; k <= 9; k++){ if(abs(j - k) >= 2) dp[i][j] += dp[i-1][k]; } } } } int solve(int n){ int cnt = 0, sum = 0; while(n){ num[++cnt] = n % 10; n /= 10; } num[cnt+1] = 0; for(int i = 1; i < cnt; i++){ for(int j = 1; j <= 9; j++){ sum += dp[i][j]; } } for(int i = 1; i < num[cnt]; i++) sum += dp[cnt][i]; for(int i = cnt - 1; i >= 1; i--){ for(int j = 0; j <= num[i] - 1; j++){ if(abs(num[i+1] - j) >= 2) sum += dp[i][j]; } if(abs(num[i+1] - num[i]) < 2) break; } return sum; } int32_t main() { init(); ll a, b; scanf("%lld %lld", &a, &b); printf("%lld\n", solve(b + 1) - solve(a)); return 0; }