这道题坑有点多啊,看着简单尼玛wa到死啊!!!!!
主要是注意中间如果还有一样的也要合并。还有就是一定要有个数限制因为只要有3个在一起马上就是可以消除的!!!!
其他看代码吧。。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
char s[500];
int dp[351][351];
struct pos
{
int value, num;
};
pos fact[400];
int main()
{
int t;
scanf("%d", &t);
int times = 1;
int k = 1;
while (t--)
{
scanf("%s", s);
//for (int i = 0; i < 200; i++)if (i % 2 == 0)s[i] = '0'; else s[i] = '1';
int reallen = 0;
int len = strlen(s);
//cout << len << endl;
int l;
for (int i = 0; i < len; i = l + 1)
{
l = i;
while (s[l] == s[l + 1])l++;
fact[reallen].num = (l - i + 1);
fact[reallen++].value = s[i];
}
for (int i = 0; i < reallen; i++)
for (int j = 0; j < reallen; j++)dp[i][j] = 1000000000;
for (int i = 0; i < reallen; i++)
{
if (fact[i].num >= 3)dp[i][i] = 1;
else
dp[i][i] = 3 - fact[i].num;
}
for (int i = 0; i < reallen - 1; i++)
{
dp[i][i + 1] = dp[i][i] + dp[i + 1][i + 1];
}
for (int l = 3; l <= reallen; l++)
{
for (int i = 0; i <= reallen - l; i++)
{
int e = i + l - 1;
if (fact[i].value == fact[e].value)
{
if (fact[i].num + fact[e].num >= 3)
dp[i][e] = min(dp[i][e], dp[i + 1][e - 1]);
else
dp[i][e] = min(dp[i][e], dp[i + 1][e - 1] + 3 - (fact[i].num + fact[e].num));
if (fact[i].num + fact[e].num < 4)//注意一定是要小于4的等于4不行,有3个马上就消除了
{
for (int j = i + 2; j <= e - 2; j += 2)
{
if (fact[j].num == 1)//同上只能等于1
{
dp[i][e] = min(dp[i][e], dp[i + 1][j - 1] + dp[j + 1][e - 1]);
}
}
}//以上是易错点,其他都还好说。
}
for (int j = i; j <e; j++)
{
dp[i][e] = min(dp[i][e], dp[i][j]+ dp[j + 1][e]);
}
}
}
printf("Case #%d: %d\n", k, dp[0][reallen - 1]);
k++;
}
return 0;
}