Problem G: 等凹数字
Description
定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?
Input
第一行一个整数T,表示数据的组数。
接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)
Output
输出一个整数,代表[L,R]中有多少等凹数字
Sample Input
2
1 100
101 200
Sample Output
0
1
HINT
小于等于2位的数字无凹峰
感觉很多数位dp都可以直接用这道题的程序改
因为这道题又有递增又要递减,还加个回文
复杂但难度也不是特别高
dp[len][pos][pre][up][down][hw]
分别表示:当前有效长度(去掉前导0后);枚举到了第pos位;上一个数字是pre
是否递增过;是否递减过;是否回文
#include<stdio.h>
#include<string.h>
#define LL long long
long long str[20], temp[20], dp[20][20][10][3][3][3];
long long Sech(LL len, LL pos, LL pre, LL up, LL down, LL hw, LL flag, LL k)
{
LL u, i, ans;
if(pos<0)
{
if(up && down && hw)
return 1;
return 0;
}
if(flag==0 && k==0 && dp[len][pos][pre][up][down][hw]!=-1)
return dp[len][pos][pre][up][down][hw];
if(flag==1) u = str[pos];
else u = 9;
ans = 0;
for(i=0;i<=u;i++)
{
temp[pos] = i;
if(k==1)
{
ans += Sech(len-(k && i==0), pos-1, i, 0, 0, hw, flag && i==u, k && (i==0));
continue;
}
if(i==pre)
{
if(hw && pos<(len+1)/2)
ans += Sech(len, pos-1, i, up, down, i==temp[len-pos], flag && i==u, k && (i==0));
else
ans += Sech(len, pos-1, i, up, down, hw, flag && i==u, k && (i==0));
}
else if(i>pre)
{
if(down==0)
continue;
if(hw && pos<(len+1)/2)
ans += Sech(len, pos-1, i, 1, down, i==temp[len-pos], flag && i==u, k && (i==0));
else
ans += Sech(len, pos-1, i, 1, down, hw, flag && i==u, k && (i==0));
}
else if(i<pre)
{
if(up)
continue;
if(hw && pos<(len+1)/2)
ans += Sech(len, pos-1, i, up, 1, i==temp[len-pos], flag && i==u, k && (i==0));
else
ans += Sech(len, pos-1, i, up, 1, hw, flag && i==u, k && (i==0));
}
}
if(flag==0 && k==0)
dp[len][pos][pre][up][down][hw] = ans;
return ans;
}
long long Jud(long long x)
{
LL len;
len = 0;
while(x)
{
str[len++] = x%10;
x /= 10;
}
return Sech(len-1, len-1, 0, 0, 0, 1, 1, 1);
}
int main(void)
{
LL T, l, r;
scanf("%d", &T);
while(T--)
{
memset(dp, -1, sizeof(dp));
scanf("%lld%lld", &l, &r);
printf("%lld\n", Jud(r)-Jud(l-1));
}
}
本文介绍了一种特殊数字——等凹数字的概念及其计数算法。等凹数字是指从高位到低位,数字先非递增再非递减,并且还是回文数。文章通过数位DP方法解决了一个具体问题:给定区间内有多少个等凹数字。

被折叠的 条评论
为什么被折叠?



