Educational Codeforces Round 61———F.Clear the String

链接:http://codeforces.com/contest/1132/problem/F

内容:

You are given a string ss of length nn consisting of lowercase Latin letters. You may apply some operations to this string: in one operation you can delete some contiguous substring of this string, if all letters in the substring you delete are equal. For example, after deleting substring bbbb from string abbbbaccdd we get the string aaccdd.

Calculate the minimum number of operations to delete the whole string ss.

Input

The first line contains one integer nn (1≤n≤5001≤n≤500) — the length of string ss.

The second line contains the string ss (|s|=n|s|=n) consisting of lowercase Latin letters.

Output

Output a single integer — the minimal number of operation to delete string ss.

Examples

input

5
abaca

output

3

input

8
abcddcba

output

4

题意:

给定一个字符串s,定义一种操作:将一串连续的字母相同的子串从原字符串删除,问一共需要多少次操作能删除整个字符串。

题解:

由于这道题是教育场(rated for div2)的F题,而且只有500来人做出来,我觉得这道题可能难度比较大;再估计了一下时间复杂度,感觉O(n^{3})的算法恐怕不行,于是冥思苦想效率更高的算法。。。

我想了很久没有任何思路只好去搜题解,不料居然是O(n^{3})的区间DP,眼珠子给我掉出来。。。

虽然没有做出来但这题的难度不算太大,直接上代码吧。

#include <bits/stdc++.h>
#define maxn 510
using namespace std;
int f[maxn][maxn],a[maxn],n; 
char s[maxn];
int main(){
	int i,j,k,len;
	scanf("%d",&n);
	scanf("%s",s);
	for(i=0;i<n;i++){
		a[i+1]=s[i]-'a'+1;
	}
	memset(f,0,sizeof(f));
	for(i=1;i<=n;i++){
		f[i][i]=1;
	}
	
	for(len=2;len<=n;len++){
		for(i=1;i+len-1<=n;i++){
			j=i+len-1;
			if(len==2){
				if(a[i]==a[j])f[i][j]=1;
				else f[i][j]=2;
				continue;
			}
			if(a[i]==a[j])f[i][j]=f[i+1][j-1]+1;
			else f[i][j]=min(f[i+1][j],f[i][j-1])+1;
			for(k=i;k<=j;k++){
				f[i][j]=min(f[i][j],f[i][k]+f[k][j]-1);
				//先将i到k删得只剩下跟k相同的(花费是f[i][k]-1),然后删从k到j 
			}
		}
	}
	cout<<f[1][n];
	return 0;
}
发布了27 篇原创文章 · 获赞 11 · 访问量 3609

猜你喜欢

转载自blog.csdn.net/Megurine_Luka_/article/details/88563478
今日推荐