F. Clear the String(字符串dp)

F. Clear the String

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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

Copy

5
abaca

output

Copy

3

input

Copy

8
abcddcba

output

Copy

4

以下来自此:https://blog.csdn.net/qq_41157137/article/details/88219615 

题意:
给你一个只含小写字母的字符串,每次只能删除一段含有一样字母区间,问最少删多少次,能删除整个字符串

分析:
定义dp[i][j]为删除区间【i,j】的最少次数

(1)如果s[i]==s[j],dp[i][j] = dp[i+1][j-1] + 1

(2)如果s[i] != s[j],dp[i][j] = min(dp[i+1][j],dp[i][j-1]) + 1

(3)枚举【i,j】的分割点k,dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j] - 1)

(1)、(2)的更新是字符串的老套路了;我模拟了样例,才有了(3)的更新,为什么不是dp[i][k] + dp[k+1][j]?因为有可能s[i]==s[k]==s[j],这三个位置可以只删一次,又因为包含s[k]的联通块删了两次,所以要减一

代码:
--------------------- 
作者:KobeDuu 
来源:CSDN 
原文:https://blog.csdn.net/qq_41157137/article/details/88219615 
版权声明:本文为博主原创文章,转载请附上博文链接!

这题真的不会,只有看别人的博客补题了

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
const int MAXN = 505;
int dp[MAXN][MAXN],n;
char s[MAXN];
int main()
{
    cin>>n;
    scanf("%s",s+1);
    for(int i = 1;i <= n; ++i) dp[i][i] = 1;
    for(int len = 2; len <= n; ++len){
        for(int l = 1,r = len;r <= n; ++l,++r){
            if(s[l] == s[r]) dp[l][r] = dp[l+1][r-1] + 1;
            else dp[l][r] = min(dp[l+1][r],dp[l][r-1]) + 1;
            for(int k = l;k <= r; ++k)
                dp[l][r] = min(dp[l][r],dp[l][k]+dp[k][r]-1);
        }
    }
    cout<<dp[1][n];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/88363022