Mountain NumberFZU-2109
题目大意:一个大于0的数字x,分写成x=a[0]a[1]a[2][3]..a[n]的形式,(比如x=1234,a[0]=1,a[1]=2,a[3]=3,a[3]=4),Mountain Number要满足对于a[2*i+1]要大于等于a[2*i]和a[2*i+2],给定范围l,r问,有多少个Mountain Number
就简单的数位dp,照着题意写就行,而且求的是数字,前导0并没有任何影响,对于全0的情况,我们把0也特别视为Mountain Number,也就消除了全0的影响。然后就根据奇偶性判断,奇数位的数要大于等于前一个,偶数位的数要小于等于前一个的数。
一开始看错题意了,以为要满足a[0]<=a[1]>=a[2],a[1]<=a[2]>=a[3],那么就是a[0]<=a[1]=a[2]=a[3]=..>=a[n],然后写着写着把自己写晕了,仔细看题目才发现,只是对奇数位的数要大于等于前后的数。
1 #include<cstdio> 2 int a[36],dp[36][10][2];//dp[i][j][k]第i数位的前一个数是j奇偶性是k的答案 3 int dfs(int p,int pre,bool jo,bool lim) 4 { 5 if(p<0) 6 return 1; 7 if(!lim&&dp[p][pre][jo]!=-1) 8 return dp[p][pre][jo]; 9 int up=(lim ? a[p] : 9),ans=0; 10 for(int i=0;i<=up;i++) 11 { 12 if(!jo&&i<=pre) 13 ans+=dfs(p-1,i,1,lim&&i==a[p]); 14 else if(jo&&i>=pre) 15 ans+=dfs(p-1,i,0,lim&&i==a[p]); 16 } 17 if(!lim) 18 dp[p][pre][jo]=ans; 19 return ans; 20 } 21 int solve(int x) 22 { 23 int n=0; 24 while(x) 25 { 26 a[n++]=x%10; 27 x/=10; 28 } 29 return dfs(n-1,9,0,1); 30 } 31 int main() 32 { 33 int t,l,r; 34 for(int i=0;i<=32;i++) 35 for(int j=0;j<=9;j++) 36 for(int k=0;k<2;k++) 37 dp[i][j][k]=-1; 38 scanf("%d",&t); 39 while(t--) 40 { 41 scanf("%d%d",&l,&r); 42 printf("%d\n",solve(r)-solve(l-1)); 43 } 44 return 0; 45 }