Codeforce-Clear the String

9 篇文章 0 订阅
7 篇文章 0 订阅

Clear the String

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 of the input contains two integers n and k (2≤n≤200; 0≤k≤n) — the length of s and the maximum number of moves you can make. The second line of the input contains the string s consisting of n lowercase Latin letters. The third line of the input contains the string t consisting of two lowercase Latin letters.

Output

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

Sample Input1

5
abaca

Sample Output1

3

Sample Input2

8
abcddcba

Sample Output2

4

题目大意

一个字符串,一次可以删去一个相同的字串,例如ABBBA可以一次性删除BBB得到AA
现在给你一个字符串,如何删除,用最小的次数删除该字符串。

思路解析

首先可以肯定的是这题用dp去解。
我们可以这样规划
dp[l,r]代表[L,R]中删除该子串的最小次数。
首先可以规划的是dp[i,i]=1。
接下来我们可以通过规划删除字符串长度的过程,最后规划出删除字符串长度为n的最优方案。
我们删除字符串时会遇到如下几种情况。
第一种
ABFJIOWOFKBA,如此你的最优解应为AxA 那么应该可以为中间的那些的最小次数+1

第二种
ABFJIOWOFKBC 或 ABFJIOWOFKBC可以视为Ax或者xC那么就是两端选其一再+1

这是已知的其中一种解,因为我们初始化的dp是0,避免逻辑上的矛盾,所以上面这一步其实就是一种初始化,规定当前[L,R]区间内至多是这么多。

当我们初始化这两种情况后,就开始考虑ABFJIOW + OFKBC 分成两部分去删除的最优解。
所以我们就得枚举这个断点在哪里,去查询最优解。

因此可以得到如下dp方程
dp[l][r] = dp[l + 1][r - 1] + 1;
dp[l][r] = min(dp[l + 1][r], dp[l][r - 1]) + 1;
dp[l][r] = min(dp[l][i] + dp[i][r] - 1, dp[l][r]);

代码如下

//#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const ll less_inf = 0x3f3f3f3f;
const char char_inf = 127;
#pragma GCC optimize(2)
#define accelerate cin.tie(NULL);cout.tie(NULL);ios::sync_with_stdio(false);
#define PI 3.141592653589793
#define EPS 1.0e-8
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
}
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void out(ll a) {
	if (a < 0)putchar('-'), a = -a;
	if (a > 9)out(a / 10);
	putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
	ll res = 1;
	while (n > 0) {
		if (n & 1)res = (res * x) % mod;
		x = (x * x) % mod;
		n >>= 1;
	}
	return res;
}
#define read read()
int dp[505][505];
int main()
{
	accelerate;
	int n;
	string s;
	cin >> n >> s;
	memset(dp, 0, sizeof(dp));
	for (int i = 0; i < s.size(); i++)
		dp[i][i] = 1;
	int l, r;
	for (int len = 2; len <= n; len++)
		for (l = 0; l < n - 1; l++)
		{
			if ((r = (l + len - 1)) >= n)break;
			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 i = l; i <= r; i++)
				dp[l][r] = min(dp[l][i] + dp[i][r] - 1, dp[l][r]);
		}
	cout << dp[0][n - 1] << endl;
}

By-Round moon

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Round moon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值