• [LOJ6274] 数字


    前言

    这是一篇普通博客

    失踪人口开学啦!真哒!回归啦!

    然而令人窒息的教练使得我依然要鸽题解

    题目

    USOJ

    LOJ

    讲解

    一眼数位DP

    但众所周知,数位DP的题怎么能用数位DP做呢 (我就没这么过过题)

    所以我们使用我最喜欢的搜索!当然是记忆化搜索

    定义(dp[i][lx][rx][ly][ry])表示状态在第(i)位(二进制下),(x)(y)是否各自抵着他们各自的上下界的方案数

    我们定义(V)是最后按位与起来的答案其中一个

    特殊的,我们考虑边界,也就是(i=0)时,当然就是具体的一种情况,返回(1)

    普通的,我们考虑当前位置(i)

    要满足(x_i lor y_i = T_i)

    如果(x_i land y_i = V_i)

    很明显,当(V_i=0)时,有(00,01,10)三种情况,当然我们要选择(3)个当中的最大值来转移当前位置

    (V_i=1),只有(11)一种情况,所以直接累加就好了

    至于(lx,rx,ly,ry,T_i),这些只是限制条件,用来判断是否可以转移,在过程中顺便处理一下就好了

    没听懂就看看代码,挺简单的

    代码

    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 65;
    int n;
    int t[MAXN],LX[MAXN],RX[MAXN],LY[MAXN],RY[MAXN];
    int dx[4] = {1,1},dy[4] = {0,1,0,1};
    LL dp[MAXN][2][2][2][2];
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    void Put1(LL x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    void Put(LL x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x);
    	if(c >= 0) putchar(c);
    }
    template <typename T>T Max(T x,T y){return x > y ? x : y;}
    template <typename T>T Min(T x,T y){return x < y ? x : y;}
    template <typename T>T Abs(T x){return x < 0 ? -x : x;}
    
    void work(int *a,LL val)
    {
    	int len = 0;
    	while(val) a[++len] = val % 2,val >>= 1;
    	n = Max(n,len);
    }
    LL dfs(int x,bool lx,bool rx,bool ly,bool ry)
    {
    	if(!x) return 1;
    	if(dp[x][lx][rx][ly][ry] != -1) return dp[x][lx][rx][ly][ry]; 
    	dp[x][lx][rx][ly][ry] = 0;
    	LL MAX = 0;
    	for(int i = 0;i < 4;++ i)
    	{
    		int t1 = dx[i],t2 = dy[i];
    		if((t1 | t2) != t[x]) continue;
    		if(lx && t1 < LX[x]) continue;
    		if(rx && t1 > RX[x]) continue;
    		if(ly && t2 < LY[x]) continue;
    		if(ry && t2 > RY[x]) continue;
    		bool p1 = (lx && LX[x] == t1),p2 = (rx && RX[x] == t1),p3 = (ly && LY[x] == t2),p4 = (ry && RY[x] == t2);
    		if(!(t1&t2)) MAX = Max(MAX,dfs(x-1,p1,p2,p3,p4));//按位与起来是0,有00,01,10三种情况,要取最大值 
            else dp[x][lx][rx][ly][ry] += dfs(x-1,p1,p2,p3,p4);//就这一种情况啊,当然要累加 
    	}
    	dp[x][lx][rx][ly][ry] += MAX;
    	return dp[x][lx][rx][ly][ry];
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	memset(dp,-1,sizeof(dp));
    	work(t,Read());
    	work(LX,Read());
    	work(RX,Read());
    	work(LY,Read());
    	work(RY,Read());
    	Put(dfs(n,1,1,1,1));
    	return 0;
    }
    

    后记

    (loj)跑了(Rank1),(72ms),嘿嘿嘿

  • 相关阅读:
    自编码变分贝叶斯(转载)
    加载Pytorch中的预训练模型及部分结构的导入
    pytorch读入图片并显示np.transpose(np_image, [1, 2, 0])
    高斯分布、多维高斯分布、各向同性的高斯分布及多元高斯分布之间的KL散度
    pytorch中的上采样(上采样,转置卷积,上池化,PixelShuffle)
    卷积算法动画演示
    PL/SQL编程基础
    PL/SQL Dev 调试
    PL/SQL Dev的安装与连接远程数据库
    Bean Form DTO VO Entity
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/13395232.html
Copyright © 2020-2023  润新知