题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=15http://
题目分析:最开始我想的是用栈来做,结果发现每次求最小不是那么容易的事情。再说这道题划分在动态规划之中也是有它的原因的。这里用一个数组dp来记录从字符串的位置i到位置j至少需要添加的括号数。当然如果i到j只包含一个字符,那dp[i][j]一定为1;否则就赋值成一个比较大的数。如果第i个字符和第j个字符匹配,那么dp[i][j]=dp[i+1][j-1];遍历i与j之间的所有字符,将dp[i][j] 更新为min(dp[i][j], dp[i][k]+dp[k+1][j])。
参考代码:
#include<stdio.h>
#include<string.h>
int dp[100][100];
bool match(char a, char b)
{
if((b == ')' && a == '(') || (b == ']' && a == '['))
return true;
else
return false;
}
int main()
{
char str[102];
int t;
int i,j,k,l;
int nLen;
scanf("%d",&t);
getchar();
while(t--)
{
gets(str);
nLen = strlen(str);
for(l = 1; l <= nLen; ++l)
{
for(i = 0; i + l <= nLen; ++i)
{
j = i + l - 1;
if(i == j)
dp[i][j] = 1;
else
dp[i][j] = 100;//字符串的最大长度
if(match(str[i], str[j]))
dp[i][j] = dp[i + 1][j - 1];
for(k = i; k <= j; ++k)
if(dp[i][k] + dp[k + 1][j] < dp[i][j])
dp[i][j] = dp[i][k] + dp[k + 1][j];
}//end for i
}//end for l
printf("%d\n",dp[0][nLen-1]);
}//end while(t--)
}