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


    点此看题面

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

    数位(DP)

    显然数位(DP)吧。

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

    转移时枚举(a)(b)这一位的填写状况,就能确定(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
    ",DP(30,1,1,1));//求解,输出
    	return 0;
    }
    
  • 相关阅读:
    20150212-2015
    SM30维护视图添加按钮
    SAP保存操作记录CDHDR和CDPOS表
    20150123-慢慢
    20150124-轻轻
    维护 物料主数据 号码段
    ABAP DEMO-2018
    工具
    幽门螺杆菌资料收集
    MySQL 8 连接时出现 1251 和 2059 错误
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/ECNU77.html
Copyright © 2020-2023  润新知