1. 程式人生 > >HDU 5787 K-wolf Number(數位dp)

HDU 5787 K-wolf Number(數位dp)

blog typedef turn pan con target ack cnblogs freopen

http://acm.split.hdu.edu.cn/showproblem.php?pid=5787

題意:
給出一個範圍[l,r]和整數k,求出在該範圍的數在十進制每k個相鄰的數都不同的數的個數。

思路:

看題意就是挺明顯的數位dp,一開始不想開5維數組,想用哈希記錄狀態,不過錯了,可能是姿勢不太對。。然後就開了5維數組,因為K最多就5嘛,註意好前導0的問題即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5
#include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const int maxn = 1e6 + 5; 16
17 ll L,R; 18 int K; 19 int dig[30]; 20 ll dp[30][11][11][11][11]; 21 22 bool check(int pre1,int pre2,int pre3,int pre4,int x) 23 { 24 if(K==2) return x!=pre4; 25 else if(K==3) return x!=pre4 && x!=pre3; 26 else if(K==4) return x!=pre4 && x!=pre3 && x!=pre2;
27 else return x!=pre4 && x!=pre3 && x!=pre2 && x!=pre1; 28 } 29 30 ll dfs(int pos, int pre1, int pre2, int pre3, int pre4, int lead ,int limit) 31 { 32 if(pos==-1) return lead!=1; 33 if(!limit && dp[pos][pre1][pre2][pre3][pre4]!=-1) return dp[pos][pre1][pre2][pre3][pre4]; 34 int up=limit?dig[pos]:9; 35 ll tmp = 0; 36 for(int i=0;i<=up;i++) 37 { 38 if(lead && i==0) tmp+=dfs(pos-1,pre1,pre2,pre3,pre4,lead,limit&&i==dig[pos]); 39 else if(check(pre1,pre2,pre3,pre4,i)) 40 tmp+=dfs(pos-1,pre2,pre3,pre4,i,0,limit&&i==dig[pos]); 41 } 42 if(!limit) dp[pos][pre1][pre2][pre3][pre4]=tmp; 43 return tmp; 44 } 45 46 ll solve(ll x) 47 { 48 int pos=0; 49 while(x) 50 { 51 dig[pos++]=x%10; 52 x/=10; 53 } 54 return dfs(pos-1,10,10,10,10,1,1); 55 } 56 57 int main() 58 { 59 //freopen("in.txt","r",stdin); 60 while(~scanf("%lld%lld%d",&L,&R,&K)) 61 { 62 memset(dp,-1,sizeof(dp)); 63 printf("%lld\n",solve(R)-solve(L-1)); 64 } 65 return 0; 66 }

HDU 5787 K-wolf Number(數位dp)