cf Educational Codeforces Round 61 F. Clear the String

原题:
F. Clear the String
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a string s of length n 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 s.

Input
The first line contains one integer n (1≤n≤500) — the length of string s.

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

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

Examples
input
5
abaca
output
3
input
8
abcddcba
output
4

中文:

给你一个字符串,每次可以去掉字符串中的一个连续的子串,这个连续的子串必须所有的字符都相同,问你最少去掉多少次可以将整个字符串去掉。

代码:

#include<bits/stdc++.h>
using namespace std;
 
typedef long long ll;
const int maxn=501;
int dp[maxn][maxn];
int n;
char s[maxn];
 
int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n)
    {
        cin>>&s[1];
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            dp[i][i]=1;
 
        for(int len=1;len<n;len++)
        {
            for(int i=1;i<=n-len;i++)
            {
                int j=i+len;
                dp[i][j]=dp[i+1][j]+1;
                for(int k=i+1;k<=j;k++)
                {
                    if(s[i]==s[k])
                        dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]);
                }
            }
        }
        cout<<dp[1][n]<<endl;
    }
    return 0;
}

思路:

区间dp

设置状态为dp[i][j]表示i到j的子串全部去掉需要的最少步数,设字符串为s

状态转移方程为

d p [ i ] [ j ] = m i n ( d p [ i + 1 ] [ j ] + 1 , d p [ i + 1 ] [ k − 1 ] + d p [ k ] [ j ] ) dp[i][j]=min(dp[i+1][j]+1,dp[i+1][k-1]+dp[k][j]) dp[i][j]=min(dp[i+1][j]+1,dp[i+1][k1]+dp[k][j])

d p [ i + 1 ] [ j ] + 1 dp[i+1][j]+1 dp[i+1][j]+1表示去掉第i个字符,
d p [ i + 1 ] [ k − 1 ] + d p [ k ] [ j ] dp[i+1][k-1]+dp[k][j] dp[i+1][k1]+dp[k][j]表示当第k个字符与第i个字符相同时,可以先把中间[i+1,k-1]个字符串先处理了,使得第i个字符与第k个字符相邻,因为第i个字符与第k个字符相同,那么在执行dp[k][j]时可以在消除第k个字符时顺带将第i个字符一并消除。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值