⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 最大符号匹配 动态规划.txt

📁 NUAA ACM OJ源码
💻 TXT
字号:
#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;

//最大符号匹配 动态规划
/*
输入:
([][][)
(])(
((()))
[][][]

输出:
6
2
6
6
*/
#define NMAX 102
int f[NMAX][NMAX];//f[i][j],从第i位到第j位子串的匹配情况
char str[NMAX];//将shuru[]后移一位得道,str[0]不用,方便写转移方程
char shuru[NMAX];

void print(int num)
{	//调试时打印f[][]
	int i,j;
	for(i=1;i<=num;i++) cout<<i<<" ";
	cout<<endl;
	for(i=1;i<=num;i++)
	{
		for(j=1;j<=num;j++)
			cout<<f[i][j]<<" ";
		cout<<endl;
	}
	cout<<endl;
	system("pause");
}
int cal(int num)
{
	int i,j,max,k,m;
	memset(f,0,sizeof(f));
	for(i=1;i<=num;i++) f[i][i]=0;
	for(i=1;i<num;i++)
	{
		if((str[i]=='('&&str[i+1]==')')||(str[i]=='['&&str[i+1]==']'))
			f[i][i+1]=1;
	}
	for(k=3;k<=num;k++)
	{//要枚举的字符串长度
		for(i=1;i<=num-k+1;i++)
		{//要枚举的字符串的起始位置
			j=i+k-1;//结束位置
			max=f[i][j-1];
			if(str[j]==')'||str[j]==']') 
			{	//这种情况才可能增加匹配数
				for(m=i;m<j;m++)
				{//枚举要与末括号匹配的括号位置
					if(m>i)
					{//如果m不是首位,max由三部分组成(1+str[m]之前+str[m]之后的匹配数)
						if((str[m]=='('&&str[j]==')')||(str[m]=='['&&str[j]==']'))
						{
							if(max<1+f[i][m-1]+f[m+1][j-1])
								max=1+f[i][m-1]+f[m+1][j-1];
						}
						else if(max<f[i][m-1]+f[m+1][j-1]) max=f[i][m-1]+f[m+1][j-1];
					}
					else
					{//如果m是首位,max由两部分组成(1+str[m]之后的匹配数)
						if((str[m]=='('&&str[j]==')')||(str[m]=='['&&str[j]==']'))
						{
							if(max<1+f[m+1][j-1])
								max=1+f[m+1][j-1];
						}
						else if(max<f[m+1][j-1]) max=f[m+1][j-1];
					}
				}
			}
			f[i][j]=max;
		}
	}
//	print(num);
	return f[1][num];
}

int main()
{
	int i,num;
	scanf("%s",&shuru);
	while(strcmp(shuru,"end")!=0)
	{
		num=strlen(shuru);
		i=0;
		str[0]='s';
		do
		{
			str[i+1]=shuru[i];
			i++;
		}while(shuru[i-1]!='\0');
		cout<<2*cal(num)<<endl;
		scanf("%s",&shuru);
	}
    return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -