1. 程式人生 > >UVA 11361 Investigating Div-Sum Property

UVA 11361 Investigating Div-Sum Property

pac page 自身 mem 則無 alt print printf 不同

題目鏈接:UVA-11361

題意:給定a,b,k。求在a和b之間,有多少數字滿足自身是k的倍數,且該數字的各數位和也是k的倍數。

思路:典型的數位dp,需要註意的是各數位和m1的範圍,否則無法記憶化,可以熟悉一下數位dp的模板。

代碼:

技術分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #include<queue>
 7 using namespace
std; 8 typedef long long LL; 9 10 LL k; 11 LL a[20]; 12 LL ten[20]; 13 LL dp[20][200][10010];//不同題目狀態不同 14 LL dfs(LL pos,LL m1,LL m2,bool limit) 15 { 16 if(m1>=200) return 0; 17 if(pos==-1) 18 { 19 if(m1==0 && m2==0) return 1; 20 return 0; 21 } 22 if(!limit && dp[pos][m1][m2]!=-1
) return dp[pos][m1][m2]; 23 LL up=limit?a[pos]:9; 24 LL ans=0; 25 for(LL i=0;i<=up;i++) 26 ans+=dfs(pos-1,((m1-i)%k+k)%k,((m2-i*ten[pos])%k+k)%k,limit && i==a[pos]); 27 if(!limit) dp[pos][m1][m2]=ans; 28 return ans; 29 } 30 LL solve(LL x) 31 { 32 LL pos=0; 33 while
(x) 34 { 35 a[pos++]=x%10; 36 x/=10; 37 } 38 return dfs(pos-1,0,0,true); 39 } 40 int main() 41 { 42 #ifdef LOCAL 43 freopen("in.txt","r",stdin); 44 freopen("out.txt","w",stdout); 45 #endif 46 ten[0]=1; 47 for(int i=1;i<20;i++) ten[i]=ten[i-1]*10; 48 LL t; 49 scanf("%lld",&t); 50 for(LL tt=1;tt<=t;tt++) 51 { 52 memset(dp,-1,sizeof(dp)); 53 LL a,b; 54 scanf("%lld%lld%lld",&a,&b,&k); 55 printf("%lld\n",solve(b)-solve(a-1)); 56 } 57 return 0; 58 }
View Code

UVA 11361 Investigating Div-Sum Property