XJTUOJ #1080 qz的不卡常数

题目

https://oj.xjtuicpc.com/problem/1080

思路

我大E了啊,没细想,一发模拟交上去被防出去,全防出去了啊(WA 0)。

其实是一道区间DP题(括号匹配挺多都是区间DP),我们用(DP[i][j])表示第(i)位到第(j)位最少要填充几个。

转移过程就是套路枚举区间断点,用之前的结果拼成当前的答案,i,j,k枚举(区间DP常规套路),复杂度是(O(n^3))的,珂以接受。

转移方程见代码,因为要分类讨论,比较烦。

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int dp[101][101];
int main(){
	int i,j,k,n,ans=0;
	char s[101];
	freopen("T.in","r",stdin);
	freopen("myans.out","w",stdout);
	scanf("%s",s+1);
	n=strlen(s+1);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(i<=j) dp[i][j]=inf;
			else dp[i][j]=0;
	for(i=1;i<=n;i++){
		dp[i][i]=1;
		for(j=i-1;j>=1;j--){
			for(k=j;k<i;k++){
				if(s[i]==')'){
					if(s[k]=='(') dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]);
					else dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
				}
				else if(s[i]==']'){
					if(s[k]=='[') dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]);
					else dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
				}
				else{
					dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
				}
			}
		}
	}
	ans=dp[1][n];
	printf("%d",ans);
	// system("pause");
	return 0;
}
原文地址:https://www.cnblogs.com/landmine-sweeper/p/14262419.html