CF 1714 D. Color with Occurrences 思维 1600

12 篇文章 0 订阅

题意:一个字符串 t,n 个子字符串,用子字符串给字符串 t 上色,求最小操作次数的方法。

思路:求出字符串 t 每个字符最长前缀下标 i, i 到当前字符能被子字符串上色。然后从结尾倒着一直往前跳就能求出答案。

代码:

#include<bits/stdc++.h>
#define pb push_back
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10, P = 1e9 + 7, mod = 998244353;
PII pr[110];
int dp[110];
void solve(){
	string t;
	int n;
	cin >> t >> n;
	vector<string> s(n);
	for(int i = 1; i <= t.size(); i++) dp[i] = 0x3f3f3f3f;
	for(int i = 0; i < n; i++) cin >> s[i];
	for(int i = 0; i < t.size(); i++){
		for(int j = 0; j < n; j++)
			if(i + s[j].size() <= t.size() && t.substr(i, s[j].size()) == s[j])
				for(int k = 1; k <= s[j].size(); k++)
					if(dp[i + k] > dp[i] + 1){
						dp[i + k] = dp[i] + 1;
						pr[i + k] = {i, j};
					}
 	}
 	int l = t.size();
 	if(dp[l] == 0x3f3f3f3f){
 		cout << -1 << endl;
 		return;
	}
	vector<PII>v;
	while(l > 0){
		v.pb(pr[l]);
		l = pr[l].first;
	}	 
	cout << v.size() << endl;
	for(int i = 0; i < v.size(); i++)
		cout << v[i].second + 1 << " " << v[i].first + 1 << endl;
}                
int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int tt;
	cin >> tt;
	while(tt--) {
		solve();
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值