【数位dp && 状态压缩】Balanced Numbers SPOJ - BALNUM

Problem Description

让你求闭合区间内,平衡数的个数。
平衡数:数字由0-9组成,如果是偶数得有奇数个,如果是奇数得有偶数个。
例:12313:1, 3有偶数个,2有奇数个。所以它是要给平衡数

思路:

统计0-9对应的数字是偶还是奇,0是偶,奇是1,可以状态压缩。
还需要处理一个点,就是数字有没有出现过。一开始默认是0,所以偶也默认是0,如果没有出现过就是满足,如果出现过就是不满足。所以我们还需要状态压缩记录 数字是否出现过。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[25][1200][1200];
int a[25];
bool judge(int now, int ex)
{
    //printf("%d %d\n", now, ex);
    for(int i = 0; i < 10; i++)
    {
      //  printf("ei %d %d\n", ex, i);
        if( !((1<<i) & ex) ) continue;
      //  printf("ni %d %d\n", now, i);
        if(i%2 == 0) {
            if(!((1<<i) & now)) return 0;
        }
        else {
            if((1<<i) & now) return 0;
        }

    }
    return 1;
}
ll dfs(int pos, int now, int ex, int sta, int limit)//到了第几位,当前状态,是否存在的状态,是否出现过除了0以外的数字,限制
{
    if(pos < 0) {
        if(judge(now, ex)) return 1;//判断是否满足
        else return 0;
    }
    if(!limit && dp[pos][now][ex] != -1) return dp[pos][now][ex];
    int up = limit ? a[pos] : 9;
    ll res = 0;
    for(int i = 0; i <= up; i++)
    {
        int ex1 = ex|(1<<i), now1 = now^(1<<i);//更新存在的数字,和当前状态
        //printf("res = %lld\n", res);
        res += dfs(pos-1, (sta || i != 0) ? now1 : 0, (sta || i != 0) ? ex1 : 0, sta || i != 0, limit && i == a[pos]);
        //printf("res = %lld\n", res);
    }
    if(!limit) return dp[pos][now][ex] = res;
    return res;
}
ll solve(ll x)
{
    int pos = 0;
    while(x)
    {
        a[pos++] = x%10;
        x /= 10;
    }
    return dfs(pos-1, 0, 0, 0, 1);
}
int main()
{
    int T;
    cin >> T;
    ll lt, rt;
    memset(dp, -1, sizeof(dp));
    while(T--)
    {
        cin >> lt >> rt;
        cout << solve(rt) - solve(lt-1) << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值