题目链接:点击查看

题目大意:给出 n 个灯泡以及其初始状态(开或关),每次操作可以将任意一个灯泡的状态置反,问最少需要操作多少次,可以使得所有开着的灯泡之间相距 k 个单位

题目分析:因为需要满足所有开着的灯泡之间需要相距 k 个单位,这也就形成了一个划分,那就是根据位置对 k 取模后的结果,将 n 个灯泡划分成了 k 组,每一组都相互独立,显然如果需要满足条件的话,只能存在某一组的灯泡有连续的状态为开启的灯泡,其余 k - 1 组的灯泡的状态必须都为关闭才行,这样一来我们可以通过枚举这 k 组来计算答案维护最小值,对于某一组答案的计算,我们可以视为两个部分相加而成:

  1. 将其余 k - 1 组中状态为开启的灯泡关闭
  2. 当前组中,用最少的步数使得至多含有一个连续的开启的灯泡段

对于情况二,可以利用 dp 线性完成,对于情况一,可以在维护 dp 的同时维护一些变量 O( 1 ) 计算得到

这里讲一个实现比较简单,但是需要一定思维量的转换方法,记初始时状态为开启的灯泡个数为 sum ,第 i 组状态为开启的灯泡个数为 dp[ i ] ,那么情况一对应着的答案就是 sum - dp[ i ] ,情况二对应着:将开着的灯视为 1 ,关着的灯视为 -1 ,那么求出 mmax 为最大连续字段和即可,这样情况二就可以用 dp[ i ] - mmax 来表示了,最终答案就是维护 sum - mmax 的最小值即可

参考至:https://blog.nowcoder.net/n/0aa657fdce7040b0bfb48799070fec5a

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;vector<int>val[N];int solve(const vector<int>&a)
{int max_ending=0,mmax=0;for(int i=0;i<a.size();i++){max_ending=max(max_ending+a[i],0);mmax=max(mmax,max_ending);}return mmax;
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){int n,k;string s;cin>>n>>k>>s;int sum=count(s.begin(),s.end(),'1');for(int i=0;i<n;i++)val[i].clear();for(int i=0;i<n;i++)val[i%k].push_back(s[i]=='1'?1:-1);int ans=inf;for(int i=0;i<k;i++)ans=min(ans,sum-solve(val[i]));printf("%d\n",ans);}return 0;
}

CodeForces - 1353E K-periodic Garland(思维+dp)相关推荐

  1. Codeforces Round #701 (Div. 2) E. Move and Swap 思维 + dp

    传送门 文章目录 题意: 思路: 题意: 思路: 由于是按层来的,所以我们肯定先按照层来分组. 定义dp[i]dp[i]dp[i]为红棋在位置iii的时候的最大得分和. 先考虑不换的情况,我们对于每个 ...

  2. CodeForces - 1550E Stringforces(二分+状压dp)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,只包含前 kkk 个小写字母以及通配符 ???,现在可以将通配符替换成任意的前 kkk 个字母中的一个.设 f[i]f[i]f[i] 为 ...

  3. 思维dp ---- CF41D Pawn [可达状态统计dp]

    题目链接 题目大意: 解题思路: 如果没有 k+1∣∑wk+1|\sum wk+1∣∑w 的限制的话就是个简单的 dp dp[i][j]=max(dp[i+1][j−1],dp[i+1][j+1])d ...

  4. D.Digits 思维dp 取log乘积变成加法

    题目链接 题目大意: 就是给你nnn个数和一个数字ddd,问你从这n个数中挑出若干个数,使得这些数的乘积最后的一个数字是d,并且结果是最大的,问你要挑出哪些数字? n∈[1,1e5],ai∈[1,10 ...

  5. CodeForces - 1409F Subsequences of Length Two(dp)

    题目链接:点击查看 题目大意:给出一个字符串 s ,再给出一个长度为 2 的字符串 t ,最多可以进行 m 次操作,每次操作可以选择 s 中的一个字符修改为其他任意一个字符,问如何操作可以使得 t 作 ...

  6. 算法训练 K好数(dp+动态规划)

    问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22 ...

  7. 【牛客 - 696D】小K的雕塑(dp,鸽巢原理,01背包类问题)

    题干: 链接:https://ac.nowcoder.com/acm/contest/696/D 来源:牛客网 小K有n个雕塑,每个雕塑上有一个整数 若集合T中的每一个元素在n个雕塑上都能找得到,则称 ...

  8. Codeforces ----- Kefa and Dishes [状压dp]

    题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...

  9. codeforces - 1216F WIFI(单调队列+DP)

    传送门 题意:有n个房间,需要把n个房间全部连上网,可以使用i的代价直接将第i个房间连上网.有一些房间可以放路由器,代价也是他的标号i,路由器可以使得i-k,到i+k之间所有房间通上网,求最小代价使得 ...

最新文章

  1. 2021年大数据Flink(十):流处理相关概念
  2. 为ThinkPad T420增加一根4G内存
  3. oracle数据导入-dblink方式
  4. numpy的cumsum ()函数
  5. asp.net 导出Excel 设置格式
  6. 有气质的人都在看什么?
  7. leetcode 941. 有效的山脉数组
  8. AJAX方式进行验证码的判断(JS方式)
  9. 95-38-055-Buffer-UnpooledDirectByteBuf
  10. ACM 竞赛高校联盟 练习赛 第六场 韩梅梅的抽象画(图论水题)
  11. CCF CSP201912-1 报数
  12. NMF扩展名是什么文件
  13. 林语堂的《武则天传》读后感
  14. Python代码破解路由器config.bin从入门到放弃
  15. [暑假]简单认识一下常用的字体 <<微软雅黑 黑体 和 宋体>>
  16. C++笔记——第十一篇 多态 深入剖析
  17. 【PR 基础】PR界面简介
  18. 人脸识别SVM算法实现--参考麦子学院彭亮机器学习基础5.2
  19. 【C++】读取txt文件中指定行的内容
  20. 图论、建图--bzoj1539: [POI2005]Dwu-Double-row

热门文章

  1. 把linux制作成内存系统,把内存当硬盘,提速你的linux系统
  2. 初始Docker-Docker和虚拟机的差别
  3. Method Area(方法区)
  4. 虚拟存储器(虚拟内存Vitual Memory)
  5. weblogic 扫描不到jar包的类问题解决方案
  6. 代码演示:获取锁时被中断
  7. ThreadLocal的两种用法
  8. RocketMQ的Producer详解之分布式事务消息(原理分析)
  9. web.xml文件中可以配置哪些内容?
  10. c语言 变量 定义 使用,C语言为什么要规定对所用到的变量要“先定义,后使用”...