El número de combinaciones (combinaciones lógicas) que se pueden utilizar para obtener el resultado esperado del plan de 100 días Expresión del día 16 Dificultad

objetivo de aprendizaje:

¡Continuaré actualizando mis ideas únicas de algoritmos, con la esperanza de traerles una expansión de pensamiento diferente!
Si lo encuentra útil, por favor, siga y apoye!
Su aliento es lo que me mantiene en marcha!
! ! !

Contenido de aprendizaje:

Enlace de red Niuke
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

tiempo de estudio:

2022.4.4

Salida de aprendizaje:

Análisis:
1. Como se muestra a continuación, use el rango para tratar de encontrar la ley
inserte la descripción de la imagen aquí
2. El método del método 1 es muy complicado, y una de las razones es que el valor que se ha calculado recursivamente antes no se retiene, lo que lleva a cálculo repetido, por lo que podemos usar Planificación dinámica, cambiar dp
para crear una tabla Verdadera para almacenar todos los casos Verdaderos
Crear una tabla Falsa para almacenar todos los casos Falsos
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

using System;
class test
{
    
    
    const int MOD = 1000000007;
    //const long Max =(long)( Math.Pow(10,9)+7);
    static void Main()
	{
    
    
		string input = Console.ReadLine();  //输入表达式
        string bo= Console.ReadLine();   //输入目标逻辑值
        bool isdesired = bo == "false" ? false : true;

        long count= dp(input.ToCharArray(), isdesired);
        Console.WriteLine(count);
	}
	public static long dp(char[] express, bool desired)
	{
    
    
        if (express.Length == 0|| express == null)
        {
    
    
			return 0;
        }
        if (!IsValid(express))
        {
    
    
            return 0;
        }

        //开始dp
        int length = express.Length;

        //建立二维尝试模型
        //T代表True表 F代表Fasle表
        long[,] T = new long[length, length];
        long[,] F = new long[length, length];

        for (int i = 0; i < length; i += 2)
        {
    
    
            T[i, i] = (express[i] == '1' ? 1 : 0);
            F[i, i] = (express[i] == '0' ? 1 : 0);
        }

        //从左往右,从下往上
        //i代表列 我们只需要对偶数列做判断
        for (int i = 2; i < length; i += 2)
        {
    
    
            //然后我们从下往上,找到对角线位置往上2格的格子
            //这个for循环是为了从下往上遍历完这一列
            //j代表行 我们只需要对偶数行做判断
            for (int j = i - 2; j >= 0; j -= 2)
            {
    
    
                //k是逻辑运算符的位置
                for (int k = j; k < i; k += 2)
                {
    
    
                    //T[j, (k-1)]是前一个0/1位
                    //T[(k-1) + 2, i]是当前的0/1位置


                    //为什么这里的位置这么奇葩?其实仔细分析,我们就会发现
                    //这两个表达式都是压在对角线上的,对角线就代表当前格子是T还是F
                    //并且对角线我们是很容易填出来的
                    if (express[k + 1] == '&')
                    {
    
    
                        //如果是& 那么T要成立 两边都得为True
                        T[j, i] += (T[j, k] * T[k + 2, i]);
                        //如果是& 那么F要成立
                        //那么当前位置为F的情况下,前面位置T/F都行
                        //那么当前位置为T的情况下,前面位置F才行
                        F[j, i] += ((F[j, k] + T[j, k]) * F[k + 2, i] +
                                    F[j, k] * T[k + 2, i]);
                    }
                    else if (express[k + 1] == '^')
                    {
    
    
                        //如果是^ 那么要T成立
                        //那么当前位置为F的情况下,前面位置T才行行
                        //那么当前位置为T的情况下,前面位置F才行
                        T[j, i] += (T[j, k] * F[k + 2, i] + F[j, k] * T[k + 2, i]);
                        //如果是^ 那么要F成立
                        //那么当前位置为F的情况下,前面位置F才行行
                        //那么当前位置为T的情况下,前面位置T才行
                        F[j, i] += (F[j, k] * F[k + 2, i] + T[j, k] * T[k + 2, i]);
                    }
                    else if (express[k + 1] == '|')
                    {
    
    
                        //如果是| 那么要T成立
                        //那么当前位置为F的情况下,前面位置T才行行
                        //那么当前位置为T的情况下,前面位置F/T都行
                        T[j, i] += (T[j, k] * F[k + 2, i] +
                                (F[j, k] + T[j, k]) * T[k + 2, i]);
                        //如果是| 那么要F成立
                        //那么当前位置为F的情况下,前面位置F才行行
                        //那么当前位置为T的情况下,前面位置啥都不行
                        F[j, i] += (F[j, k] * F[k + 2, i]);

                    }
                    T[j, i] %= MOD;
                    F[j, i] %= MOD;
                }


            }
        }



        return desired ? T[0, length - 1] : F[0, length - 1];
    }

	public static bool IsValid(char[] express)
    {
    
    
        //首先需要判断长度是否是奇数
        if (express.Length % 2 == 0)
        {
    
    
			return false;
        }

		//其次判断偶数位是否都是0/1
		for(long i = 0; i < express.Length; i += 2)
        {
    
    
            if (express[i] != '0' && express[i] != '1')
            {
    
    
                return false;
            }
        }

        //然后判断奇数位是否都是 & ^ |
        for(long i = 1; i < express.Length; i += 2)
        {
    
    
            if (express[i] != '&' && express[i] != '^' && express[i] != '|')
            {
    
    
                return false;
            }
        }
        return true;
    }
}

Supongo que te gusta

Origin blog.csdn.net/m0_48781656/article/details/123953923
Recomendado
Clasificación