首页 > 其他 > 详细

【ECNU77】位与数对个数(数位DP)

时间:2019-08-19 19:39:01      阅读:152      评论:0      收藏:0      [点我收藏+]

点此看题面

大致题意:\(\sum_{x=0}^{a-1}\sum_{y=0}^{b-1}[(x\&y)<k]\)

数位\(DP\)

显然数位\(DP\)吧。

我们设\(f_{n,f1,f2,f3}\)表示当前处理到第\(n\)位,\(a\)是否卡在上界,\(b\)是否卡在上界,\(k\)是否卡在上界的方案数。

转移时枚举\(x\)\(y\)这一位的填写状况,就能确定\(k\)这一位的填写状况了。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define LL long long
#define Reg
using namespace std;
int a,b,k;LL f[35][2][2][2];
I LL DP(CI x,CI f1,CI f2,CI f3)//数位DP
{
    if(!~x) return 1;//若处理完
    RI l1=f1?a>>x&1:1,l2=f2?b>>x&1:1,l3=f3?k>>x&1:1;//求a,b,k这一位上界
    if(f[x][f1][f2][f3]) return f[x][f1][f2][f3];LL res=0;//若搜过,直接返回
    l1&&l2&&l3&&(res+=DP(x-1,f1,f2,f3));//1,1
    l1&&(res+=DP(x-1,f1,f2&&!l2,f3&&!l3));//1,0
    l2&&(res+=DP(x-1,f1&&!l1,f2,f3&&!l3));//0,1
    res+=DP(x-1,f1&&!l1,f2&&!l2,f3&&!l3);//0,0
    return f[x][f1][f2][f3]=res,res;//记下答案并返回
}
int main()
{
    RI Tt,i;scanf("%d",&Tt);W(Tt--)
        scanf("%d%d%d",&a,&b,&k),--a,--b,--k,memset(f,0,sizeof(f)),//读入,清空
        printf("%lld\n",DP(30,1,1,1));//求解,输出
    return 0;
}

【ECNU77】位与数对个数(数位DP)

原文:https://www.cnblogs.com/chenxiaoran666/p/ECNU77.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!