当前位置: 首页 > article >正文

Codeforces Round 642 (Div. 3) E. K-periodic Garland(DP+前缀和)

题目链接

https://codeforces.com/contest/1353/problem/E

思路

d p [ i ] [ 0 / 1 ] dp[i][0/1] dp[i][0/1]分别表示第 i i i个字符是 0 0 0或者 1 1 1时的前 i i i个字符组成的花环所需的最少操作次数。

如果第 i i i个字符变为 1 1 1,分为两种情况:第一种情况是第 i − k i-k ik个字符必须为 1 1 1,且 [ i − k + 1 , i − 1 ] [i-k+1,i-1] [ik+1,i1]中间的字符必须为 0 0 0。第二种情况是前 i − 1 i-1 i1个字符全部为 0 0 0

如果第 i i i个字符变为 0 0 0,则前 i − 1 i-1 i1个字符可以为 0 0 0 1 1 1

我们令 s u m [ i ] sum[i] sum[i]表示前 i i i个字符中 1 1 1的个数。

状态转移方程为:

i − k ≥ 0 i - k \ge 0 ik0时: d p [ i ] [ 1 ] = m i n ( s u m [ i − 1 ] , d p [ i − k ] [ 1 ] + ( s u m [ i − 1 ] − s u m [ i − k ] ) ) + ( s [ i ] ≠ ′ 1 ′ ) dp[i][1] = min(sum[i - 1], dp[i - k][1] + (sum[i - 1] - sum[i - k])) + (s[i] \ne '1') dp[i][1]=min(sum[i1],dp[ik][1]+(sum[i1]sum[ik]))+(s[i]=1)

i − k < 0 i - k < 0 ik<0时: d p [ i ] [ 1 ] = s u m [ i − 1 ] + ( s [ i ] ≠ ′ 1 ′ ) dp[i][1] = sum[i - 1] + (s[i] \ne '1') dp[i][1]=sum[i1]+(s[i]=1)

d p [ i ] [ 0 ] = m i n ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] ) + ( s [ i ] ≠ ′ 0 ′ ) dp[i][0] = min(dp[i - 1][0], dp[i - 1][1]) + (s[i] \ne '0') dp[i][0]=min(dp[i1][0],dp[i1][1])+(s[i]=0)

时间复杂度: O ( n ) O(n) O(n)

代码

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define double long double

typedef long long i64;
typedef unsigned long long u64;
typedef pair<int, int> pii;

const int N = 1e6 + 5, M = 5e5 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f3f3f3f3f;

std::mt19937 rnd(time(0));

int n, k;
int sum[N], dp[N][2];
char s[N];
void solve()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> s[i];
	}
	for (int i = 1; i <= n; i++)
	{
		sum[i] = sum[i - 1] + (s[i] == '1');
	}
	for (int i = 1; i <= n; i++)
	{
		dp[i][0] = dp[i][1] = inf;
	}
	for (int i = 1; i <= n; i++)
	{
		if (i - k >= 0)
			dp[i][1] = min(sum[i - 1], dp[i - k][1] + (sum[i - 1] - sum[i - k])) + (s[i] != '1');
		else dp[i][1] = (sum[i - 1]) + (s[i] != '1');
		dp[i][0] = min(dp[i - 1][0], dp[i - 1][1]) + (s[i] != '0');
	}
	cout << min(dp[n][0], dp[n][1]) << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int test = 1;
	cin >> test;
	for (int i = 1; i <= test; i++)
	{
		solve();
	}
	return 0;
}

http://www.kler.cn/a/521534.html

相关文章:

  • Ubuntu安装VMware17
  • DeepSeek-R1 模型及GRPO算法学习
  • java.math 包 中的 BigDecimal 类(详细案例拆解)
  • 360大数据面试题及参考答案
  • 005 单点登录
  • Java 大视界 -- Java 大数据在量子通信安全中的应用探索(69)
  • C#面试常考随笔4:int? 和 int的区别,以及int?的运用场景?
  • 数据结构与算法学习笔记----求组合数
  • 【已解决】redisCache注解失效,没写cacheConfig
  • 项目测试之Postman
  • goframe 博客分类文章模型文档 主要解决关联
  • C++进阶课程第2期——排列与组合1
  • 数据分析常用的AI工具
  • Java基础知识总结(二十二)--List接口
  • 重回C语言之老兵重装上阵(十六)C语言可变参数
  • 低代码可视化-转盘小游戏可视化-代码生成器
  • OSPF协议考点
  • 【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)
  • Python 如何进行文本匹配:difflib| python 小知识
  • [蓝桥杯 2014 省 AB] 蚂蚁感冒
  • 独立开发者产品日刊:让ChatGPT自动执行任务、AI电子阅读器、音频转视频、Android 智能助手、对话生成表单、SEO内容优化
  • 使用python实现mongodb的操作
  • C语言,无法正常释放char*的空间
  • 03-画P封装(制作2D+添加3D)
  • 《剪映5.9官方安装包》免费自动生成字幕
  • PHP根据IP地址获取地理位置城市和经纬度信息