切割 01 串 2.0

#### 题目描述

jackle 在校赛的时候出过一道 "切割 01 串" 的题目,如今他又出了一道切割 01 串的题目:

给定一个长度为 n 的 01 串,定义如下操作为一次 "切割":

将长度大于 1 的字符串分割为两个非空的连续字串,记分割出来的左侧字串 a 中 0 的出现次数为 C0,右侧字串 b 中 1 出现的次数为 C1,需要满足L≤|C0−C1|≤R。

你每次切割完,都会得到两个新 01 串,你可以继续选择这些已经被你切出来的 01 串做切割,只要满足切割条件。

jackle 想问你最多可以切割多少次?

#### 输入描述:

第一行输入 3 个整数,n (1≤n≤500),L,R (0≤L≤R≤500),分别表示字符串长度,和题目中的两个参数。

第二行输入 1 个长度为 n 的 01 串。

#### 输出描述:

输出最多能切割多少次?

输入

6 2 3
011011

输出

3

说明

其中一种切割次数最多的切法如下:
第一次切割可以切:0 ∣ 11011,然后选择 11011 这个串继续做切割。
第二次切割可以切:1 ∣ 1011,然后选择 1011 这个串继续做切割。
第三次切割可以切:1 ∣ 011。
#include<bits/stdc++.h>
using namespace std;
int n, l, r;
string s;
int c0[550], c1[550],dp[550][550];
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin>>n>>l>>r;
	cin>>s;
	s = " " + s;
	for (int i = 1; i <= n; i++)
    {
		c0[i] = c0[i - 1];
		c1[i] = c1[i - 1];
		if (s[i] == '1') c1[i]++;
		else c0[i]++;
	}
	for (int len = l+1; len<=n; len++)
    {
		for (int i = 1; i+len-1<=n; i++)
        {
			int m = i + len - 1;
			for (int j = i; j<=m-1; j++)
            {
				int C0 = c0[j] - c0[i - 1];
				int C1 = c1[m] - c1[j];
				if (abs(C0 - C1) >= l && abs(C0 - C1) <= r)
                {
					dp[i][m] = max(dp[i][m], dp[i][j] + dp[j + 1][m] + 1);
				}

			}
		}
	}
	cout<<dp[1][n]<<endl;
	return 0;
} 
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值