P6754 [BalticOI 2013 Day1] Palindrome-Free Numbers

数据范围一眼数位dp。

关键条件为如果一个数字串的一个长度大于 11 的子串也为回文串的话,那么我们也定义这个数字串为回文串。

仔细思考发现一旦两个连续的数相同(偶回文)或两个数隔一个数相同(奇回文)都是回文,所以要保证连续三个数不相同,记录前两位即可。

注意事项:

1.前导零不应为0,防止前导零影响结果,可设为-1。

2.因为前两位可能有前导零,记忆化搜索可能越界,应搜索和记录时数值+1。

3.0<=l,所以有可能将出现求负数,应特判。(提示我们数位dp的一种可能错误)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a,b,dp[20][20][20];
int sh[20];
ll dfs(int cur,bool qdl,bool lim,int x2,int x1)
{
    if(cur==0)return 1;
    if(!qdl&&!lim&&~dp[cur][x2+1][x1+1])return dp[cur][x2+1][x1+1];
    int z=lim?sh[cur]:9;
    ll sum=0;
    for(int i=0;i<=z;i++)
    {
        if(x2==i||x1==i)continue;
        sum+=dfs(cur-1,qdl&(i==0),lim&(i==z),x1,(!qdl||i)?i:-1);
    }  
    if(!qdl&&!lim)dp[cur][x2+1][x1+1]=sum;
    return sum;
}
ll find(ll x)
{
    if(x<0)return 0;
    ll ans=0;int pos=0;
    while(x>0)
    {
        sh[++pos]=x%10;
        x/=10;
    }  
    ans=dfs(pos,1,1,-1,-1);
    return ans;
}
int main()
{
    memset(dp,-1,sizeof(dp));
    scanf("%lld%lld",&a,&b);
    printf("%lld\n",find(b)-find(a-1));
    return 0;
}
posted @   storms11  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示