SPOJ - BALNUM Balanced Numbers数位DP+3进制存图

来源:互联网 发布:cast sql 意思 编辑:程序博客网 时间:2024/06/05 02:25

求n~m中奇数为偶数个,偶数为奇数个的数有多少个

话说这题我本来用2进制来存图,一维存每个数字是否出现过,一维存每个数字出现的次数,最后得到的程序Runtime error(SIGKILL)了,⊙﹏⊙b汗

其实这题应该3进制存储每次选择一个数字后的状态,0表示没出现过,1表示出现奇数次,2表示出现过偶数次

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <utility>#include <vector>#include <queue>using namespace std;#define INF 0x3f3f3f3f#define maxn 66666typedef long long LL;LL dp[25][maxn];int num[25];int cnt[10];void go(int s)//将某个状态从3进制变成数组{    for (int i = 0; i < 10; i++)    {        cnt[i] = s % 3;        s /= 3;    }}int new_s(int s, int d)//将d压入图中{    go(s);    if (cnt[d] == 0) cnt[d] = 1;    else        cnt[d] = 3 - cnt[d];    int base = 1;    s = 0;    for (int i = 0; i < 10; i++)    {        s += base * cnt[i];        base *= 3;    }    return s;}int check(int s)//检查是否符合题意{    go(s);    for (int i = 0; i < 10; i++)    {        if ((i & 1) && (cnt[i] == 1)) return 0;        if (!(i & 1) && (cnt[i] == 2))return 0;    }    //cout<<s<<endl;    return 1;}LL dfs(int i, int s, bool e,int zero){    if (i == -1) return check(s);    if (!e&&~dp[i][s]) return dp[i][s];    LL ret = 0;    int u = e ? num[i] : 9;    for (int d = 0; d <= u; d++)    {        ret += dfs(i - 1, zero&&d==0?0:new_s(s, d), e&&d == u,zero&&d==0);    }    return e ? ret : dp[i][s] = ret;}LL cal(LL n){    int cnt = 0;    while (n)    {        num[cnt++] = n % 10;        n /= 10;    }    return dfs(cnt - 1, 0, 1,1);}int main(){    int T;    scanf("%d", &T);    memset(dp, -1, sizeof(dp));    while (T--)    {        LL x, y;        scanf("%lld%lld", &x, &y);        printf("%lld\n", cal(y) - cal(x - 1));    }    return 0;}


0 0
原创粉丝点击