zoukankan      html  css  js  c++  java
  • 【DP】E. K-periodic Garland

    E. 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])转移过来,操作次数更新由(s[i]==1)负责,若(s[i])本身就为0,则新增0次操作,否则新增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),第(i)项才能为(1)(此时(pre[i-1]-pre[i-k]=0)),(dp[i][1])的状态才能从(dp[i-k][1])转移过来;或者从“令(1)(i-1)项全为(0),使得第(i)项为整个序列的第一个(1)”的状态转移过来。操作次数更新由(s[i]==0)负责,若(s[i])本身就为1,则新增0次操作,否则新增1次操作

    最后注意输入的是字符数组

    void solve() {
    	int n, k;
    	cin >> n >> k;
    	cin >> s+1;
    	for (int i = 1; i <= n; i++)
    		pre[i] = pre[i - 1] + (s[i] == '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');
    		dp[i][1] = min(dp[p][1] + pre[i - 1] - pre[p], pre[i - 1]) + (s[i] == '0');
    	}
    	cout << min(dp[n][0], dp[n][1]) << endl;
    	for (int i = 0; i <= n; i++) {
    		dp[i][1] = 0;
    		dp[i][0] = 0;
    		pre[i] = 0;
    	}
    }
    
  • 相关阅读:
    html5+css3中的background: -moz-linear-gradient 用法 (转载)
    CentOS 安装Apache服务
    Linux 笔记
    CURL 笔记
    Spring Application Context文件没有提示功能解决方法
    LeetCode 389. Find the Difference
    LeetCode 104. Maximum Depth of Binary Tree
    LeetCode 520. Detect Capital
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 136. Single Number
  • 原文地址:https://www.cnblogs.com/streamazure/p/12896935.html
Copyright © 2011-2022 走看看