zoukankan      html  css  js  c++  java
  • 删括号--动态规划

    采用数组模拟栈的入栈出栈 进行匹配   通过仅有  ~通过率97.3%  因为这类型的解不了 退栈进栈的方式 跟下面代码思路差不多
    但是对于下面这种情况的处理无法解决  所以换种思路结合动态规划的思路 每一次查询都有自己作用 并把作用交给下一次查找
    (()(()))
    ()() 
    删括号的时候一定要时刻保证左括号数量比右括号多或者等于(最后才等于),我们可以定义dp[i][j][k]表示考虑AA前ii个匹配了BB前jj个AA被删除部分左括号数-右括号数=k是否可行,分类讨论转移即可,最后答案就是dp[n][m][0]
    (()......) => ()          对于这种类型不知道删除外面还是只能分类讨论 按删外面试  这里代码的思路有点像“编辑路径”的算法 
    只是这里是括号匹配相对比较困难
    下面的代码思路是输入字符串转化为目标字符串 这里是第一个字符开始试 第二个试..................

    import java.util.*;
    public class Main {
    	final static int NUM = 105;
    	static int dp[][][] = new int[NUM][NUM][NUM];
    	static char a[] = new char[NUM];
    	static char b[] = new char[NUM];
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		String s1 = sc.nextLine();
    		String s2 = sc.nextLine();
    		int n = s1.length();
    		int m = s2.length();
    		for (int i = 1; i <= n; i++) {
    			a[i] = s1.charAt(i - 1);
    		}
    		for (int i = 1; i <= m; i++) {
    			b[i] = s2.charAt(i - 1);
    		}
    		dp[0][0][0] = 1; 
    		for(int i = 0 ; i < n ; i++) {
    			for(int j = 0 ;j <= m ; j++) {
    				for(int k = 0 ; k <= i ; k++) {
    					if(dp[i][j][k]!=0) {//建立在前人的基础上 !=0 证明还有( 还没匹配完
    						if(k==0 && a[i+1]==b[j+1])
    							dp[i+1][j+1][k]=1;
    						if(a[i+1]=='(')
    							dp[i+1][j][k+1]=1;
    						else if(k!=0) 
    							dp[i+1][j][k-1]=1; //能匹配到第一位是 1 为正确答案
    					}
    				}
    			}
    		}
    		if(dp[n][m][0]==1)
    			System.out.println("Possible");
    		else System.out.println("Impossible");
    	}
    }
    
    #include "pch.h"
    #include<iostream>
    const int N = 105;
    int n, m, i, j, k;
    char a[N], b[N];
    bool f[N][N][N];
    int main()
    {
    	scanf("%s%s", a + 1, b + 1);
    	n = strlen(a + 1), m = strlen(b + 1);
    	f[0][0][0] = 1;
    	for (i = 0; i < n; ++i)
    		for (j = 0; j <= m; ++j)
    			for (k = 0; k <= n; ++k)
    				if (f[i][j][k])
    					//如果前面状态有可能转化成目标状态,0进行下一操作
    				{
    					if (!k && a[i + 1] == b[j + 1])
    						//当删除正好为(),且符合目标状态 
    						f[i + 1][j + 1][k] = 1;
    					if (a[i + 1] == '(')
    						//或者为可删除的状态,先判断(,保证左括号的数量大于右括号
    						//删去(,差值k加一
    						f[i + 1][j][k + 1] = 1;
    					else if (k)
    						//凑够(),删去)差值k减一 也就是a有一部分可以满足条件 继续判断
    						f[i + 1][j][k - 1] = 1;
    				}
    	//输出()差值k为0的值
    	puts(f[n][m][0] ? "Possible" : "Impossible");
    }
    
    if else 的疑问
    if(a)
    b;
    if(c)
    d;两个if都会进入判断。
    if(a)
    b;
    else if(c)
    d;//当满足a的时候就不进入到c的判断,不满足a时,才会去判断c
    
  • 相关阅读:
    用户需求报告
    结队开发项目——七巧板NABC需求分析
    梦断代码读书笔记3
    课堂练习之环形二维数组
    结对开发之求最大子数组的溢出问题
    《代码之美》第二章读后感(一)
    软件工程项目冲刺阶段二:第五天
    软件工程项目冲刺阶段二:第四天(06-06)
    软件工程项目冲刺阶段二:第三天
    课程评价
  • 原文地址:https://www.cnblogs.com/cznczai/p/11147986.html
Copyright © 2011-2022 走看看