X - Bi-peak Number (数位dp+有上界也有下届)
2017-11-12 11:52
246 查看
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.
![](https://odzkskevi.qnssl.com/0ec7cae8c4f8085af905db6b3866a23c?v=1509936268)
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
题意:定义"特殊数"为两次先上升后下降形成的数,且第一位大于等于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;
}
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
Sample Output
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;
}
相关文章推荐
- hdu3565 Bi-peak Number (有上界和下界的数位dp)
- HDU 3565 Bi-peak Number [数位DP]
- 【数位DP】HDU3565-Bi-peak Number
- [数位dp] hdu 3565 Bi-peak Number
- HDOJ 3565 Bi-peak Number (数位DP)
- hdu 3565 Bi-peak Number 数位dp
- hdu 3565 Bi-peak Number 数位dp
- hdu_3565_Bi-peak Number(数位DP)
- hdu_3565_Bi-peak Number(数位DP)
- Codeforce 401D Roman and Numbers[数位DP+状态压缩]
- 【数位DP+离散化】Beautiful numbers CodeForces - 55D
- Codeforces 54C First Digit Law 数位dp+概率dp
- hdu3555 Bomb 【数位dp+记忆化dfs】
- HDU3709:Balanced Number(数位DP+记忆化DFS)
- 【cf】55d beautiful numbers【精妙的数位dp+离散化】
- CodeForces 401D Roman and Numbers【数位dp+状态压缩】
- [数字dp] hdu 3565 Bi-peak Number
- Gym - 100507G G. The Debut Album 数位dp+内存优化
- HDU3709:Balanced Number(数位DP+记忆化DFS)
- hdu4352 XHXJ's LIS 数位DP+状态压缩