CF1353E K-periodic Garland(动态规划)

/*
 * K-periodic Garland
 * 题意:
 * 给定长度为n的01字符串,每次操作可以改变一个字符的状态,问使得字符串中相邻1的距离为k的最小操作次数
 * 题解:
 * DP。
 * pre[i]记录前i项中1的个数。
 * dp[i][0]为使得前i项都合法,第i位为0时的最小操作次数。
 * dp[i][1]为使得前i项都合法,第i位为1时的最小操作次数。
 * 有转移方程:
 * dp[i][0]=min(dp[i-1][0],dp[i-1][1])+(s[i]==1)
 * 因为第i项为0时对合法性无影响,其合法性直接从dp[i-1][0]或者dp[i-1][1]转移过来。
 * dp[i][1]=min(dp[i-k][1]+pre[i-1]-pre[i-k],pre[i-1])+(s[i]==0)
 * 当第i-k项合法时,要让第i项为1时合法,则要保证i-k+1到i-1全为0。
 */
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
int T;
int N,K;
string s;
int pre[maxn];
int dp[maxn][2];
int main () {
    cin>>T;
    while (T--) {
        cin>>N>>K;
        for (int i=0;i<=N;i++) dp[i][0]=dp[i][1]=pre[i]=0;
        cin>>s;
        for (int i=1;i<=N;i++)
            pre[i]=pre[i-1]+(s[i-1]=='1');
        for (int i=1;i<=N;i++) {
            int p=max(0,i-K);
            dp[i][0]=min(dp[i-1][0],dp[i-1][1])+(s[i-1]=='1');
            dp[i][1]=min(dp[p][1]+pre[i-1]-pre[p],pre[i-1])+(s[i-1]=='0');
        }
        printf("%d\n",min(dp[N][0],dp[N][1]));
    }
}

猜你喜欢

转载自www.cnblogs.com/zhanglichen/p/12900914.html
今日推荐