题解:SP5449 ANARC09A - Seinfeld

可以用动态规划解决。

动态规划思想:

\(dp_{i,j}\) 表示处理到字符串的第 \(i\) 个字符,并且未配对的 { 数量为 \(j\) 时,所需的最小操作次数。

状态转移:

  • 初始化

    • \(dp_{0,0} = 0\):表示空字符串且没有未配对的 {,显然不需要任何操作。
    • 其他所有 \(dp_{0,j}\) 初始化为 INF,表示不可能的状态。
  • 状态转移方程

    • 如果当前字符是 {
      • 可以选择将它保留为 {,那么我们增加一个未配对的 {,即 \(dp_{i,j}=1+dp_{i-1,j-1}\)
      • 如果有未配对的 {,我们也可以选择将这个 { 改为 },这样可以减少一个未配对的 {,即 \(dp_{i,j}=\min(dp_{i,j},dp_{i-1,j-1})\)
    • 如果当前字符是 }
      • 可以选择将它保留为 },此时如果之前有未配对的 {,可以减少一个未配对的 {,即 \(dp_{i,j} = dp_{i-1,j-1}\)
      • 也可以选择将这个 } 改为 {,从而增加一个未配对的 {,即 \(dp_{i,j}=\min(dp_{i,j},dp_{i-1,j-1})\)

最终结果:

在处理完所有字符后,\(dp_{n,0}\) 就是最终需要的最小操作次数。

代码:

using namespace std;
char str[2001];
int main(){
	for(int cs=1;;cs++){
		scanf("%s",str);
		if(str[0]=='-')return 0;
		int N=strlen(str);
		vector<vector<int>>dp(N+1,vector<int>(N+1,1e6));
		dp[0][0]=0;
		for(int i=1;i<=N;i++){
			for(int j=0;j<=N;j++){
				if(str[i-1]=='{'){
					dp[i][j]=1+dp[i-1][j+1];
					if(j>0)dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
				}else{
					dp[i][j]=dp[i-1][j+1];
					if(j>0) dp[i][j]=min(dp[i][j],1+dp[i-1][j-1]);
				}
			}
		}
		printf("%d. %d\n",cs,dp[N][0]);
	}
}
posted @ 2024-10-02 17:40  cly312  阅读(33)  评论(0)    收藏  举报