Problem I. Increasing or Decreasing MIPT-2016 Pre-Finals Workshop, Taiwan NTU Contest, Sunday, March 27, 2016
题面:
Problem I. Increasing or Decreasing
Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 512 mebibytes
We all like monotonic things, and solved many problems about that like Longest Increasing Subsequence
(LIS). Here is another one which is easier than LIS (in my opinion).
We say an integer is a momo number if its decimal representation is monotonic. For example, 123, 321,
777 and 5566 are momo numbers; But 514, 50216 and 120908 are not.
Please answer m queries. The i-th query is a interval [li; ri], and please calculate the number of momo
numbers in it.
Input
The first line contains an integer m.
Each of the following m lines contains two integers li; ri.
• 1 ≤ m ≤ 105
• 1 ≤ li ≤ ri ≤ 1018
Output
For each query, please output the number of momo numbers in that range.
Example
standard input | standard output |
2 1 100 100 200 |
100 48 |
思路:
数位dp
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MP make_pair 4 #define PB push_back 5 typedef long long LL; 6 typedef pair<int,int> PII; 7 const double eps=1e-8; 8 const double pi=acos(-1.0); 9 const int K=1e6+7; 10 const int mod=1e9+7; 11 12 LL dp[30][15][3]; 13 int num[30]; 14 LL dfs(int pos,int s,int pre,int led,int lmt) 15 { 16 if(pos<1) return !led; 17 if(!lmt&&~dp[pos][pre][s]) return dp[pos][pre][s]; 18 int mx=lmt?num[pos]:9; 19 LL ans=0; 20 for(int i=0;i<=mx;i++) 21 if(led) 22 ans+=dfs(pos-1,0,i,!i&&led,lmt&&i==mx); 23 else 24 { 25 if(s==0&&i>pre) 26 ans+=dfs(pos-1,1,i,!i&&led,lmt&&i==mx); 27 else if(s==0&&i<pre) 28 ans+=dfs(pos-1,2,i,!i&&led,lmt&&i==mx); 29 else if(s==0&&i==pre) 30 ans+=dfs(pos-1,0,i,!i&&led,lmt&&i==mx); 31 else if(s==1&&i>=pre) 32 ans+=dfs(pos-1,1,i,!i&&led,lmt&&i==mx); 33 else if(s==2&&i<=pre) 34 ans+=dfs(pos-1,2,i,!i&&led,lmt&&i==mx); 35 } 36 //printf("lm:%d dp[%d][%d][%d]:%I64d\n",lmt,pos,pre,s,ans); 37 if(!lmt) dp[pos][pre][s]=ans; 38 return ans; 39 } 40 LL go(LL x) 41 { 42 if(x<1) return 0; 43 int cnt=0; 44 LL ans=0; 45 while(x) 46 num[++cnt]=x%10,x/=10; 47 for(int i=0;i<num[cnt];i++) 48 ans+=dfs(cnt-1,0,i,!i,0); 49 return ans+dfs(cnt-1,0,num[cnt],0,1); 50 } 51 52 int main(void) 53 { 54 LL m,l,r; 55 cin>>m; 56 memset(dp,-1,sizeof dp); 57 while(m--) 58 { 59 scanf("%lld%lld",&l,&r); 60 //printf("%I64d\n",go(r)); 61 printf("%lld\n",go(r)-go(l-1)); 62 } 63 return 0; 64 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。