欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Codeforces Round 642 (Div. 3) E. K-periodic Garland(DP+前缀和)

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

2025/5/11 15:13:16 来源:https://blog.csdn.net/weixin_74754298/article/details/145379709  浏览:    关键词: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 doubletypedef 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;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词