spoj Balanced Numbers(数位dp)

一个数字是Balanced Numbers,当且仅当组成这个数字的数,奇数出现偶数次,偶数出现奇数次

一下子就相到了三进制状压,数组开小了,一直wa,都不报re,

使用记忆化搜索,dp[i][s] 表示长度为i,状态为s,时,满足条件的balance number的个数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef  long long LL;
const int INF = 1<<30;
/*

*/
int num[30];
LL dp[30][60000];

int getNum(int sta)
{
    int tmp1, tmp2;
    for (int i = 0; i <= 9; ++i)
    {
        tmp1 = i &1;
        tmp2 = sta % 3;
        if (tmp1==0 && tmp2==2)//偶数出现了偶数次
            return 0;
        if (tmp1 == 1 && tmp2 == 1)//奇数出现了奇数次
            return 0;
        sta /= 3;
    }
    return 1;
}

int getSta(int x, int sta)
{
    int val = 1;
    int newSta = sta;
    for (int i = 0; i < x; ++i)
    {
        val *= 3;
        sta /= 3;
    }
    int times = sta % 3;
    if (times == 0 || times == 1)
        return newSta + val;
    else
        return newSta -  val;
}
LL dfs(int pos, int sta, bool zero, bool flag)
{
    if (pos == 0) return getNum(sta);
    if (!flag && dp[pos][sta] != -1) return dp[pos][sta];
    int end = flag ?  num[pos] : 9;
    LL ans = 0;
    for (int i = 0; i <= end; ++i)
        ans += dfs(pos - 1, (zero&&i==0)?0:getSta(i, sta),zero&&i==0 ,flag&&i == end);
    if (!flag)
        dp[pos][sta] = ans;
    return ans;
}
LL calc(LL n)
{
    int len = 0;
    while (n)
    {
        num[++len] = n % 10;
        n /= 10;
    }
    return dfs(len, 0, true, true);
}
int main()
{
    memset(dp, -1, sizeof(dp));
    int t;
    LL l, r;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%lld%lld", &l, &r);
        printf("%lld\n", calc(r) - calc(l - 1));
    }
    return 0;
}
时间: 2024-12-24 03:56:52

spoj Balanced Numbers(数位dp)的相关文章

Balanced Numbers数位dp

三进制搞下, 0  表示没出现过,  第i位为1 表示 i出现了奇数次,  2表示i 出现了偶数次. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #includ

SPOJ BALNUM Balanced Numbers(数位dp)

Balanced Numbers Time Limit:123MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ BALNUM Description Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced n

SPOJ10606 BALNUM - Balanced Numbers(数位DP+状压)

Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1)      Every even digit appears an odd number of times in its decimal representation 2)      Every odd digit appears an even numb

spoj 10606 Balanced Numbers 数位dp

题目链接 一个数称为平衡数, 满足他各个数位里面的数, 奇数出现偶数次, 偶数出现奇数次, 求一个范围内的平衡数个数. 用三进制压缩, 一个数没有出现用0表示, 出现奇数次用1表示, 出现偶数次用2表示, 这样只需要开一个20*60000的数组. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_

cf55dBeautiful numbers数位dp

想到 最小公倍数 其余的就好搞了 ,可是没想到 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <

[Codefoces 401D]Roman and Numbers 数位dp

http://codeforces.com/problemset/problem/401/D 题目大意:给定一个数字n,将n的每一位数字重新排列,求在这些排列数之中可以被n整除的方法数. 解题思路: 暴力超时-- 大多数人的写法是进行位压缩,不过那样的话需要2^18*100 的空间,效率比较低,重复状态数较多,处理起来也不方便,这一题是给出了512M的空间.但是如果空间再小一倍,前者的方法就无能为力了. 发现有一种对于数位dp来说比较好的状态压缩方式,直接根据数码x出现的次数进行状态压缩.比如说

uva 10712 - Count the Numbers(数位dp)

题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a,b:问说在a到b之间有多少个n. 解题思路:数位dp,dp[i][j][x][y]表示第i位为j的时候,x是否前面是相等的,y是否已经出现过n.对于n=0的情况要特殊处理前导0,写的非常乱,搓死. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using na

poj 3340 Barbara Bennett&#39;s Wild Numbers(数位DP)

Barbara Bennett's Wild Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3153   Accepted: 1143 Description A wild number is a string containing digits and question marks (like 36?1?8). A number X matches a wild number W if they hav

CodeForces 55D Beautiful numbers 数位DP+数学

题意大概是,判断一个正整数区间内有多少个整数能被它自身的每一个非零的数字整除. 因为每一个位置上的整数集s = {0,1,2,3,4,5,6,7,8,9} lcm(s) = 2520 现在有一个整数t是由s中一个或者多个数字构成的,记为abcde,显然t = a*10^4+b*10^3+c*10^2+d*10^1+e 要使得t能被a,b,c,d,e整除,必然有t % lcm(a,b,c,d,e) = 0 因为a,b,c,d,e去重之后一定是s的一个子集,所以lcm(s)一定是lcm(a,b,c,