长度为偶数的,01相间的子段的最多个数(dp

这是一个关于字符串处理的问题,博客内容描述了一种算法,用于计算给定字符串中满足特定条件(长度为偶数,WF交替出现)的子串(恋串)数量。通过动态规划方法,维护以W和F结尾的最长恋串长度,并计算每个位置的最大恋串数量的平均值,最终输出总和。
摘要由CSDN通过智能技术生成

永远在一起
思路:
f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1] 表示以第 i i i 个字符为 W / F W/F W/F 结尾的最长恋串的长度
长度为 k k k 的一个「恋串」 p p p 中,以 p [ k ] p[k] p[k] 结尾的「恋串」数量为 k / 2 ( 向 下 取 整 ) k/2(向下取整) k/2

例如 WFWFWF 中,长度为6,就有 WF,WFWF,WFWFWF 共 3 个「恋串」。
WFWFW长度为5,有FW,FWFW,两个「恋串」。
其实就是算贡献,一个长度为 k k k 的最长恋串找长度为偶数的子恋串,显然有 k / 2 k/2 k/2 个。

如果不限定长度为偶数,每次的贡献应该是 k − 1 k-1 k1

AC代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int f[maxn][2];
// 恋串是一个子段,长度为偶数,WF交替出现 
// f[i][0] 是以W结尾的恋串的长度 
// FWFWFW 
void work()
{
	string s;cin >> s;n=s.size();s = "@" + s;
	ll ans = 0;
	for(int i = 1; i <= n; ++i){
		if(s[i] == 'W') f[i][0] = f[i-1][1] + 1;
		else if(s[i] == 'F') f[i][1] = f[i-1][0] + 1;
		else f[i][0] = f[i-1][1] + 1, f[i][1] = f[i-1][0] + 1;	
		ans += max(f[i][0], f[i][1]) / 2;
	}
	cout << ans;
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值