链接: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来人做出来,我觉得这道题可能难度比较大;再估计了一下时间复杂度,感觉的算法恐怕不行,于是冥思苦想效率更高的算法。。。
我想了很久没有任何思路只好去搜题解,不料居然是的区间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;
}