Codeforces 1353 E. K-periodic Garland(DP)

37 篇文章 0 订阅

在这里插入图片描述

题意:

给你一个长度为 n n n 01 01 01 字符串和一个整数 k k k,每次操作你可以选择一个字符并改变其状态,要使字符串中相邻 1 1 1 的距离为 k k k,问最少需要操作几次。

  1. 当前 i − 1 i - 1 i1 项合法时,第 i i i 项为 0 0 0 ,那么前 i i i 项必定合法
  2. 当前 i − k i - k ik 项合法时,第 i 项为 1 ,那么仅当第 i − k i - k ik 1 1 1,且 i − k + 1 , i − 1 i - k + 1 , i - 1 ik+1i1 项为 0 0 0 时,前 i i i 项合法。

AC代码:

const int N = 1e6 + 50;
int pre[N];	  // pre[i] 为前 i 项 1 的个数
int dp[N][2]; //dp[i][0] 为前 i 项都合法 , 第 i 位为 0 的最小操作次数
//dp[i][1] 为前 i 项都合法 , 第 i 位为 1 的最小操作次数
char s[N];

int main()
{
	int t;
	sd(t);
	while (t--)
	{
		int n, k;
		sdd(n, k);
		ss(s + 1);
		rep(i, 0, n)
			dp[i][0] = dp[i][1] = pre[i] = 0;
		rep(i, 1, n)
			pre[i] = pre[i - 1] + s[i] - '0';
		rep(i, 1, n)
		{
			int p = max(0, i - k);
			dp[i][0] = min(dp[i - 1][0], dp[i - 1][1]) + (s[i] == '1');
			dp[i][1] = min(pre[i - 1], dp[p][1] + pre[i - 1] - pre[p]) + (s[i] == '0');
		}
		pd(min(dp[n][0], dp[n][1]));
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值