Fork me on GitHub

删括号--动态规划

采用数组模拟栈的入栈出栈 进行匹配   通过仅有  ~通过率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
posted @ 2019-07-07 21:39  cznczai  阅读(257)  评论(0编辑  收藏  举报