1. 程式人生 > >HYSBZ - 1026 windy數 [數位DP]

HYSBZ - 1026 windy數 [數位DP]

pos 絕對值 規模 處理 BE size name contain 數字

windy定義了一種windy數。不含前導零且相鄰兩個數字之差至少為2的正整數被稱為windy數。 windy想知道,
在A和B之間,包括A和B,總共有多少個windy數?

Input

  包含兩個整數,A B。

Output

  一個整數

Sample Input【輸入樣例一】 1 10 【輸入樣例二】 25 50

Sample Output【輸出樣例一】 9 【輸出樣例二】 20Hint

【數據規模和約定】

100%的數據,滿足 1 <= A <= B <= 2000000000 。

方法:

裸的數位dp,特殊處理一下前導0就好

 1 #include<iostream>
 2
using namespace std; 3 #include<cstdio> 4 #include<vector> 5 #include<cstring> 6 typedef long long ll; 7 ll a,b; 8 ll f[100][13]; 9 int number[100]; 10 ll dfs(int bit,int pre,int limit,int zero){ 11 if(bit==-1){ 12 return 1;} 13 if(limit==0&&f[bit][pre]!=-1LL&&zero==0
) 14 return f[bit][pre]; 15 int up = limit?number[bit]:9; 16 int ans = 0; 17 for(int i=0;i<=up;i++){ 18 int d = pre - i;//位數之間的差 19 if(d<0)//取絕對值 20 d*=-1; 21 if(zero==0&&d<2)//排除不符合題意的情況 22 continue; 23 ans = ans + dfs(bit-1
,i,limit&&i==number[bit],zero&&i==0); 24 } 25 if(!limit&&!zero) 26 f[bit][pre] = ans; 27 return ans; 28 } 29 ll get(ll x){ 30 int num = 0; 31 memset(number,0,sizeof(number)); 32 ll pt = x; 33 while(pt>0LL){ 34 number[num++]=pt%10; 35 pt/=10LL; 36 } 37 num-=1; 38 memset(f,-1,sizeof(f)); 39 ll ans = dfs(num,12,1,1); 40 return ans; 41 } 42 int main(){ 43 while(scanf("%lld%lld",&a,&b)!=EOF){ 44 if(a<b) 45 swap(a,b); 46 ll ans = get(a) - get(b-1LL); 47 printf("%lld\n",ans); 48 } 49 return 0; 50 }

HYSBZ - 1026 windy數 [數位DP]