[数位dp] lightoj 1205 Palindromic Numbers

题意:给定范围内是回文数的个数。

思路:

dp[site][len]  site位的回文长度是len。

需要一个负责数组 ok存每位放的数。

然后就是dfs了,就是取len 的中间值mid

超过mid的话 就看看ok里面之前对称的那个数 判断是否相等

相等才能放进入下一位。

注意判断前导0,和这个oj必须用long long。

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
//2014年9月24日10:30:25
long long dp[22][22];
int num[22],ok[22];
long long dfs(int site,int n,int zero,int f)
{
    if(site==0) return 1;
    if(!f&&!zero&&dp[site][n]!=-1) return dp[site][n];
    int len=f?num[site]:9;
    long long ans=0;
    for(int i=0; i<=len; i++)
    {
        if(zero)
        {
            if(i==0) ans+=dfs(site-1,n-1,zero&&i==0,f&&i==len);
            else
            {
                ok[site]=i;
                ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
            }
        }
        else
        {
            int mid=(n+1)/2;
            if(n%2)
            {
                if(site==mid) ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
                else if(site>mid)
                {
                    ok[site]=i;
                    ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
                }
                else
                {
                    if(ok[n+1-site]==i) ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
                }
            }
            else
            {
                if(site>mid)
                {
                    ok[site]=i;
                    ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
                }
                else
                {
                    if(ok[n+1-site]==i) ans+=dfs(site-1,n,zero&&i==0,f&&i==len);
                }
            }
        }
    }
    if(!f&&!zero) dp[site][n]=ans;
    return ans;
}
long long solve(long long x)
{
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%10;
        x/=10;
    }
    return dfs(cnt,cnt,1,1);
}
int main()
{
    int t,cas=1;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        long long x,y;
        scanf("%lld%lld",&x,&y);
        if(x>y) swap(x,y);
        printf("Case %d: %lld\n",cas++,solve(y)-solve(x-1));
    }
    return 0;
}
//2014年9月24日11:26:45
时间: 2024-12-24 17:23:13

[数位dp] lightoj 1205 Palindromic Numbers的相关文章

LightOJ 1205 - Palindromic Numbers (数位dp)

LightOJ 1205 - Palindromic Numbers (数位dp) ACM 题目地址:SPOJ MYQ10 Mirror Number 题意: 求[a,b]中回文的个数. 分析: 是SPOJ MYQ01的简单版...其实有非递归方法的. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * Blog: http://blog.csdn.net/hcbbt * File: 1205.cpp * Create Date: 2014-08-

LightOJ 1205 Palindromic Numbers

数位DP.... Palindromic Numbers Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when

lightOJ 1205(Palindromic Numbers数位DP)

Palindromic Numbers Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Submit Status Description A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In

找规律/数位DP HDOJ 4722 Good Numbers

题目传送门 1 /* 2 找规律/数位DP:我做的时候差一点做出来了,只是不知道最后的 is_one () 3 http://www.cnblogs.com/crazyapple/p/3315436.html 4 数位DP:http://blog.csdn.net/cyendra/article/details/11606209 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9

[数位dp] spoj 10738 Ra-One Numbers

题意:给定x.y,为[x,y]之间有多少个数的偶数位和减去奇数位和等于一. 个位是第一位. 例子: 10=1-0=1 所以10是这样的数 思路:数位dp[i][sum][ok] i位和为sum 是否含有前导0. 然后就是因为有负数 所以根据范围把0设置为100 然后最后和等于101则为所求的数. 代码: [cpp] view plaincopyprint? #include"cstdlib" #include"cstdio" #include"cstrin

[数位dp] spoj 10606 Balanced Numbers

题意: 对于一个数的每个位上的数. 对于每个奇数,如果出现必须出现偶数次. 对于每个偶数,如果出现必须出现奇数次. 思路: 用三进制存储每个数出现的状态,0没出现,1出现奇数次,2出现偶数次. 然后其他和普通数位dp就一样了. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #i

数位DP CF 55D Beautiful numbers

题目链接 题意:定义"beautiful number"为一个数n能整除所有数位上非0的数字 分析:即n是数位所有数字的最小公倍数的倍数.LCM(1到9)=2520.n满足是2520的约数的倍数.dp[len][val][lcm]一维为数的位数,一维为%2520的值(保存原数不可能,也没必要,2520是可行的最小公倍数最大的一个),一维为当前数位的lcm,判断满足的条件是val%lcm==0.这题离散化2520的约数,否则空间开不下. #include <bits/stdc++.

【数位DP】CF55D Beautiful numbers

$dp[x][p][pp]$表示第x位,当前已有数字mod 2520(1~9数字的lcm)为p,当前各位数字的lcm为pp 观察到数组太大,考虑压缩,第三维lcm最多只有9个数字,打表发现最多只有48个状态,压掉第三维即可 打表用一个状压然后set维护(广搜也可以)即可 有一个坑点:题目里似乎没有说关于0的事情(即数字里出现0)但是有人在CF上打这个比赛的时候问了出题人,碰到0不要管即可!!! 打表代码: 1 set<int>s; 2 inline void Make(int x){ 3 in

LightOJ - 1205:Palindromic Numbers (数位DP&amp;回文串)

A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In this problem you will be given two integers i j, you have to find the number of palindromic numbers between i and j