fzu 2109 Mountain Number 数位DP
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2109
题意:
如果一个>0的整数x,满足a[2*i+1] >= a[2*i]和a[2*i+2],则这个数为Mountain Number。
给出L, R,求区间[L, R]有多少个Mountain Number。
思路:
数位DP,判断当前是偶数位还是奇数位(从0开始),如果是偶数位,那么它要比前一个数的值小,
如果是奇数位,那么它要比前一个数的值大。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 int num[20]; 7 int dp[12][2][12]; 8 int dfs(int cur, int mark, int last, int limit) 9 { 10 if(cur < 0) return 1; 11 if(!limit && dp[cur][mark][last] != -1) return dp[cur][mark][last]; 12 13 int ret = 0; 14 int up = limit ? num[cur] : 9; 15 for(int i = 0; i <= up; i++) 16 { 17 if(mark == 0 && i <= last) ret += dfs(cur-1, mark^1, i, limit && i == up); 18 else if(mark == 1 && i >= last) ret += dfs(cur-1, mark^1, i, limit && i == up); 19 } 20 if(!limit) dp[cur][mark][last] = ret; 21 return ret; 22 } 23 int slove(int x) 24 { 25 int len = 0; 26 while(x) 27 { 28 num[len++] = x%10; 29 x /= 10; 30 } 31 memset(dp, -1, sizeof(dp)); 32 return dfs(len-1, 0, 9, 1); 33 } 34 int T; 35 int main() 36 { 37 //freopen("in.txt", "r", stdin); 38 scanf("%d", &T); 39 while(T--) 40 { 41 int l, r; 42 scanf("%d%d", &l, &r); 43 printf("%d\n", slove(r) - slove(l-1)); 44 } 45 return 0; 46 }