Bi-peak Number (數位dp+有上界也有下屆)
阿新 • • 發佈:2019-01-22
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.
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]. InputThe first line of the input is an integer T (T <= 1000), which stands for the number of test cases you need to solve.
Each case consists of two integers “A B” (without quotes) (0 <= A <= B < 2^64) in a single line.
OutputFor the kth case, output “Case k: v” in a single line where v is the maximum score. If no bi-peak number exists, output 0. Sample Input
Sample Output
A number is called bi-peak if it is a concatenation of two peak numbers.
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]. InputThe first line of the input is an integer T (T <= 1000), which stands for the number of test cases you need to solve.
Each case consists of two integers “A B” (without quotes) (0 <= A <= B < 2^64) in a single line.
OutputFor the kth case, output “Case k: v” in a single line where v is the maximum score. If no bi-peak number exists, output 0. Sample Input
3 12121 12121 120010 120010 121121 121121
Case 1: 0 Case 2: 0 Case 3: 8
題意:定義"特殊數"為兩次先上升後下降形成的數,且第一位大於等於0,沒有前導零,問所有滿足條件的數中,位數和最大的是多少。
思路:(注意一點就是資料要是有unsigned_int64,wa了好幾發)
由於結果不滿足區間減法,所以不能像通常那樣計算cal(b)-cal(a-1),正確的處理方法是,在dfs時儲存2個標記,一個標記字首是否達上界,另一個標記是否達下界。然後就是狀態分析了: s=0:前導0的狀態; s=1:第一個山峰的上坡,且不能立馬下坡; s=2:第一個山峰的上坡,且最後一點能看成是最高點,下一個點可以是下坡; s=3:第一個山峰的下坡; s=4:第二個山峰的上坡,且不能立馬下坡; s=5:第二個山峰的上坡,且最後一點能看成是最高點,下一個點可以是下坡; s=6:第二個山峰的下坡; s=-1:其餘不合法的狀態。程式碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned __int64 LL; #define inf 0x7f7f7f7f int a[30],b[30]; int dp[20][10][8]; int dfs(int pos,int pre,int sta,int limitx,int limity){ if(pos==-1)return sta==6?0:-1; if(!limitx&&!limity&&dp[pos][pre][sta]!=inf) return dp[pos][pre][sta]; int minn=limitx?a[pos]:0; int maxx=limity?b[pos]:9; int res=-1; for(int i=minn;i<=maxx;i++) { int s=sta; if(sta==0&&i) s=1; else if(sta==1) { if(i>pre) s=2; else s=-1; } else if(sta==2) { if(i<pre) s=3; else if(i==pre) s=-1; } else if(sta==3 && i>=pre) { if(i) s=4; else s=-1; } else if(sta==4) { if(i>pre) s=5; else s=-1; } else if(sta==5) { if(i<pre) s=6; else if(i==pre) s=-1; } else if(sta==6 && i>=pre) s=-1; if(s!=-1) { int tmp=dfs(pos-1,i,s,limitx&&i==minn,limity&&i==maxx); if(tmp!=-1) res=max(res,i+tmp); } } if(!limitx&&!limity) dp[pos][pre][sta]=res; return res; } int main() { int t,cas=0; memset(dp,0x7f,sizeof(dp)); scanf("%d",&t); while(t--) { printf("Case %d: ",++cas); LL x,y; scanf("%I64u%I64u",&x,&y); int pos=0; for(;y;x/=10,y/=10) a[pos]=x%10,b[pos++]=y%10; int ans=dfs(pos-1,0,0,1,1); if(ans==-1) ans=0; printf("%d\n",ans); } return 0; }