• 【反转(开关问题)】Face The Right Way


    • Step1 Problem:

    [原题]N头牛排成了一列。每头牛头向前或向后。为了让所有的牛都面向前方,农夫约翰买了一台自动转向的机器。这个机器在购买时就必须设定一个数值K,机器每操作一次恰好使K头连续的牛转向。求让所有牛都能面向前方需要的最少操作次数M和对应的最小的K.

    • Step2 Ideas:

     如果按照枚举做肯定会TLE,首先排除。
    交换区间翻转的顺序对结果是没有影响的。而且没有必要对同一个区间进行两次以上的翻转。因此问题转化成了求需要被翻转区间的集合。
    f[i]:区间[i, i+K-1] 进行可反转的话为1, 否则为0。
    因此首先从最左侧牛开始考虑,如果该牛朝向前方,则不需要翻转这个区间;反之如果该牛朝后,则必须要处理这个区间,并且再次之后不需要考虑此最左的区间,区间范围-1。循环往返,即可求出最少翻转次数。

    • Step3 Code:

    #include<iostream>
    #include<stdio.h>
    #include<iomanip>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<set>
    #define mem(a,x) memset(a,x,sizeof(a));
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn = 5e3+5;
    int n, dir[maxn], f[maxn];
    
    int calc(int k)
    {
        mem(f, 0);
        int res = 0;
        int sum = 0;
        for(int i = 0;i + k <= n; i++)
        {
            if((dir[i] + sum) % 2)
            {
                res++;
                f[i] = 1;
            }
            sum += f[i];
            if(i - k + 1 >= 0) sum -= f[i - k + 1];
        }
        for(int i = n - k + 1; i < n; i++)
        {
            if((dir[i] + sum) % 2) return -1;
            if(i - k + 1 >= 0) sum -= f[i - k + 1];
        }
        return res;
    }
    
    int main()
    {
        cin >> n;
        for(int i = 0; i < n; i++)
        {
            char c;
            cin >> c;
            dir[i] = (c == 'B');
        }
    //    for(int i = 0;i < n; i++) cout << dir[i] << ' ';
    //    puts("");
        int k = 1, m = n;
        for(int i = 1;i <= n; i++)
        {
            int x = calc(i);
            if(x >= 0 && m > x)
            {
                k = i;
                m = x;
            }
        }
        cout << k << ' ' << m << endl;
        return 0;
    }
  • 相关阅读:
    2017ecjtu-summer training #4 CodeForces 731C
    HDU 1232 并查集
    2017ecjtu-summer training #3 POJ3264
    2017ecjtu-summer training #4 UESTC 30
    斑羚飞渡 贪心
    Codeforces Round #565 (Div. 3) D. Recover it!
    P3398 仓鼠找sugar lca
    P3146 [USACO16OPEN]248 dp
    P1955 [NOI2015]程序自动分析 离散化
    P2949 [USACO09OPEN]工作调度Work Scheduling 贪心
  • 原文地址:https://www.cnblogs.com/zyysyang/p/11093455.html
Copyright © 2020-2023  润新知