布尔运算,DFS记忆化搜索

题目

给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。

示例 1:

输入: s = “1^0|0|1”, result = 0
输出: 2
解释: 两种可能的括号方法是
1^(0|(0|1))
1^((0|0)|1)

示例 2:

输入: s = “0&0&0&1^1|0”, result = 1
输出: 10

提示:

  • 运算符的数量不超过 19 个

解题思路

  1. 将表达式能够产生值的部分保存在一个数组dp中。
  2. 遍历表达式中的符号,能够将左右两部分分成两个子表达式。
  3. 求出左右两个子表达式中可能出现0,1的次数,之后再求出总表达式的为0,1的值的个数。
  4. dp数组用-1初始化,这样在求解过程中就能够知道该区间是否被计算过。

代码

class Solution {
public:
    int countEval(string s, int result) {
        //直接用dfs复杂度太高,划分子问题:确定一个中间符号mid,求出左右运算的0和1的个数
        //然后就能求出【0,mid-1】和【mid + 1,right】的0和1的个数,最终扩展到【0,n】
        
        //先将数字和符号分开存放
        int n = s.size();
        int m = n / 2 + 1;
        vector<vector<vector<int>>> dp(m, vector<vector<int>>(m, vector<int>(2, -1)));

        //枚举区间【i,j】内的结果
        DFS(s, 0, n - 1, dp);

        return dp[0][m - 1][result];
    }   
private:
    void DFS(string &s, int start, int end, vector<vector<vector<int>>> &dp){
        if(start == end){
            if(dp[start / 2][start / 2][0] != -1){
                return;
            }
            dp[start / 2][start / 2][0] = 0;
            dp[start / 2][start / 2][1] = 0;
            dp[start / 2][start / 2][s[start] - '0']++;
            // cout << "i = " << start / 2 << ", = " << dp[start / 2][start / 2][1];
            return;
        }
        if(dp[start / 2][end / 2][0] != -1){
            return;
        }

        dp[start / 2][end / 2][0] = 0;
        dp[start / 2][end / 2][1] = 0;
        //然后划分子问题,列举在【i,j】区间内出现符号的位置
        for(int k = start + 1; k < end; k += 2){
            //如果这个值已经算过,就不用再递归计算
            if(dp[start / 2][(k - 1) / 2][0] == -1){
                //需要递归计算
                DFS(s, start, k - 1, dp);
            }

            if(dp[(k + 1) / 2][end / 2][0] == -1){
                //需要递归计算
                DFS(s, k + 1, end, dp);
            }

            int s0 = dp[start / 2][(k - 1) / 2][0];
            int s1 = dp[start / 2][(k - 1) / 2][1];
            int e0 = dp[(k + 1) / 2][end / 2][0];
            int e1 = dp[(k + 1) / 2][end / 2][1];
            //然后计算当前的值,即左区间的0、1的个数已知,右区间0、1的个数已知。
            if(s[k] == '&'){
                dp[start / 2][end / 2][1] += s1 * e1;
                dp[start / 2][end / 2][0] += s0 * e0 + s0 * e1 + s1 * e0;
            }
            else if(s[k] == '|'){
                dp[start / 2][end / 2][1] += s0 * e1 + s1 * e1 + s1 * e0;
                dp[start / 2][end / 2][0] += s0 * e0;
            }
            else{
                dp[start / 2][end / 2][1] += s1 * e0 + e1 * s0;
                dp[start / 2][end / 2][0] += s0 * e0 + s1 * e1;
            }
        }
        return;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于GPU栅格化的任意多边形布尔运算是指利用图形处理器(GPU)通过栅格化技术进行多边形之间的布尔运算。这种技术允许我们对两个或多个多边形进行并、交、差和异或等操作,从而得到新的多边形。 在进行布尔运算之前,需要先对多边形进行栅格化处理。栅格化将多边形离散化,将其划分为像素点的集合。然后,通过对像素点进行布尔运算,最终形成新的多边形。 具体步骤如下: 1. 首先,将两个多边形分别栅格化为两个栅格集合。 2. 对于每个像素点,判断其是否在两个栅格集合中。 3. 根据布尔运算的类型(并、交、差或异或),确定像素点是否在最终多边形中。 4. 将符合条件的像素点添加到最终多边形的栅格集合中。 5. 最后,将栅格集合转换回多边形。 基于GPU进行多边形布尔运算的优点是,它可以利用GPU的并行计算能力,大幅提高计算速度。通过将栅格化和布尔运算部分的计算任务分配到多个处理单元上同时进行,可以加快计算过程。此外,GPU在处理图形数据方面有着专门的硬件加速,可以更高效地处理大量的像素点。 综上所述,基于GPU栅格化的任意多边形布尔运算是一种高效的计算方法,可以帮助我们快速得到多边形布尔运算的结果。这对于许多应用领域,如计算机图形学、计算几何和计算机辅助设计等都具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值