Problem Description:
A peak number is defined as continuous digits {D0, D1 … Dn-1} (D0 > 0 and n >= 3), which exist Dm (0 < m < n - 1) satisfied Di-1 < Di (0 < i <= m) and Di > Di+1 (m <= i < n - 1).
A number is called bi-peak if it is a concatenation of two peak numbers.
![](http://acm.hdu.edu.cn/data/images/C301-1002-1.jpg)
The score of a number is the sum of all digits. Love8909 is crazy about bi-peak numbers. Please help him to calculate the MAXIMUM score of the Bi-peak Number in the closed interval [A, B].
A number is called bi-peak if it is a concatenation of two peak numbers.
![](http://acm.hdu.edu.cn/data/images/C301-1002-1.jpg)
The score of a number is the sum of all digits. Love8909 is crazy about bi-peak numbers. Please help him to calculate the MAXIMUM score of the Bi-peak Number in the closed interval [A, B].
分析:由于结果不满足区间减法,所以不能像通常那样计算cal(b)-cal(a-1),正确的处理方法是,在dfs时保存2个标记,一个标记前缀是否达上界,另一个标记是否达下界。然后就是状态分析了,分析清楚了也就简单了,以下是我设计的状态:
s=0:前导0的状态;
s=1:第一个山峰的上坡,且不能立马下坡;
s=2:第一个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
s=3:第一个山峰的下坡;
s=4:第二个山峰的上坡,且不能立马下坡;
s=5:第二个山峰的上坡,且最后一点能看成是最高点,下一个点可以是下坡;
s=6:第二个山峰的下坡;
s=-1:其余不合法的状态。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> #define MAX(a,b) ((a)>(b)?(a):(b)) #define N 20 #define INF 0x7f7f7f7f typedef unsigned __int64 LL; int sx[N],sy[N]; int dp[N][10][7]; int dfs(int pos,int last,int s,int fx,int fy) { if(pos==-1) return s==6?0:-1; if(!fx&&!fy&&dp[pos][last][s]!=INF) return dp[pos][last][s]; int min=fx?sx[pos]:0; int max=fy?sy[pos]:9; int ret=-1; for(int i=min;i<=max;i++) { int ns=s; if(s==0 && i) ns=1; else if(s==1) { if(i>last) ns=2; else ns=-1; } else if(s==2) { if(i<last) ns=3; else if(i==last) ns=-1; } else if(s==3 && i>=last) { if(i) ns=4; else ns=-1; } else if(s==4) { if(i>last) ns=5; else ns=-1; } else if(s==5) { if(i<last) ns=6; else if(i==last) ns=-1; } else if(s==6 && i>=last) ns=-1; if(ns!=-1) { int tmp=dfs(pos-1,i,ns,fx&&i==min,fy&&i==max); if(tmp!=-1) ret=MAX(ret,i+tmp); } } if(!fx&&!fy) dp[pos][last][s]=ret; return ret; } int main() { int t,kase=0; memset(dp,0x7f,sizeof(dp)); scanf("%d",&t); while(t--) { printf("Case %d: ",++kase); LL x,y; scanf("%I64u%I64u",&x,&y); int pos=0; for(;y;x/=10,y/=10) sx[pos]=x%10,sy[pos++]=y%10; int ans=dfs(pos-1,0,0,1,1); if(ans==-1) ans=0; printf("%d\n",ans); } return 0; }