CodeForces - 1422E Minlexes dp 模拟

https://codeforces.com/contest/1422/problem/E
给一个字符串,可以选择相同而且相邻的字母删除,问每个后缀操作后字典序最小的字符串;
选择从后往前遍历,如果当前的字母和上一个一样就可以选择删,判断一下这个和后面的字幕哪个大决定删不删;当可以删的时候,如果删掉更优,就只要删掉当前的两个,如果之前也有同样的字母因为前面已经判断并操作过,所以可以直接用之前的答案不用向后递归

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
struct str
{
	string per,suf;
	bool inc = false;
	int len = 0;
	void inser(char ch)
	{
		if(per.size()>0 && ch!=per[0])
			inc = ch < per[0];
		len++;
		if(suf.size()<2)
			suf = ch + suf;
		per = ch + per;
		if(per.size()>10)
			per.pop_back();
	}
} ans[maxn];
string s;
int main() 
{
	cin >> s;
	//ans[s.length() - 1].per = ans[s.length() - 1].suf = s[s.length() - 1];
	for (int i = s.length() - 1; i >= 0; i--)
	{
		char ch = s[i];
		//ans[i] = ans[]
		if(i+1<s.length() && s[i]==s[i+1])//能删
		{
			ans[i] = ans[i + 2];
			if(ans[i].inc && ch == ans[i].per[0] || ch < ans[i].per[0])
				ans[i].inser(ch), ans[i].inser(ch);
		}else{
			ans[i] = ans[i + 1];
			ans[i].inser(ch);
		}
	}
	for (int i = 0; i < s.length(); i++)
	{
		cout << ans[i].len << ' ';
		if(ans[i].len>10)
			cout << ans[i].per.substr(0, 5) << "..." << ans[i].suf << endl;
		else
			cout << ans[i].per << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值