Codeforces 660C - Hard Process - [二分+DP]
题目链接:http://codeforces.com/problemset/problem/660/C
题意:
给你一个长度为 n 的 01 串 a,记 f(a) 表示其中最长的一段连续 1 的长度。
现在你最多可以将串中的 k 个 0 变成 1,求操作后的 f(a)。
题解:
(说实话这道题不看tag我不一定能想得出来……)
首先考虑二分枚举答案,对于一个假定的 f(a)=x,我们需要判断能不能满足:
用 dp[i] 表示 a[i-x+1], \cdots, a[i] 的这一段上 1 的数目,那么只要存在一个 dp[i] + k \ge x 就代表这个答案 f(a)=x 是可行的。
另外,考虑到二分的边界问题比较难处理,故在区间被缩得比较小的时候可以改用暴力枚举。
同时,考虑到还有输出的问题,可以在让二分的check(mid)函数不是单纯返回 0,1,还可以再返回一个数代表答案子串的位置。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> P; #define mp(x,y) make_pair(x,y) #define fi first #define se second const int maxn=3e5+10; int n,k; int a[maxn]; int f[maxn]; P check(int x) { int mx=0, p=x; for(int i=1;i<=x;i++) f[i]=f[i-1]+a[i], mx=max(mx,f[i]); for(int i=x+1;i<=n;i++) { f[i]=f[i-1]-a[i-x]+a[i]; if(f[i]>mx) mx=f[i], p=i; } return mp(mx+k>=x,p); } int main() { cin>>n>>k; for(int i=1;i<=n;i++) scanf("%d",&a[i]); int l=k, r=n, ans, pos; while(l<=r) { if(r-l<=5) { for(int mid=r;mid>=l;mid--) { P res=check(mid); if(!res.fi) continue; ans=mid, pos=res.se; break; } break; } int mid=(l+r)/2; if(check(mid).fi) l=mid; else r=mid; } cout<<ans<<endl; for(int i=1;i<=pos-ans;i++) printf("%d ",a[i]); for(int i=pos-ans+1;i<=pos;i++) printf("1 "); for(int i=pos+1;i<=n;i++) printf("%d ",a[i]); }
转载请注明出处:https://dilthey.cnblogs.com/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 手把手教你更优雅的享受 DeepSeek
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现