1. 程式人生 > 實用技巧 >XJTUOJ #1080 qz的不卡常數

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;
}