Greedy:The Water Bowls(POJ 3185)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Greedy:The Water Bowls(POJ 3185)相关的知识,希望对你有一定的参考价值。

                技术分享

                  水池

  题目大意:给定一个20的数组,全都是0和1,可以翻一个数改变成另一个数(0或者1),但是其左右两边的数都会跟着变为原来的相反数,问你怎么用最小的操作数使全部数变成0

  这一题的:满足

    1:翻转次序不改变结果

    2.  从特定次序翻转以后左侧的元素不会再改变

    其实就是3276的变形,只是他这次固定变三个数,而且是一前一后,我们把方向dir的查看往前挪一个数就好了,但是这样我们就不能知道第一个数是否需要翻转,所以我们分两种情况来讨论就好了

    一开始我想着像3276那样枚举,可是1<<20次实在是太大了,结果TLE

    

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;
static int bowls[21], if_flip[21];

int solve(void);
int get_step(int);

int main(void)//开关问题
{
    for (int i = 1; i <= 20; i++)
        scanf("%d", &bowls[i]);

    printf("%d\\n", solve());
    return EXIT_SUCCESS;
}
int solve()//所有输入都能有一个固定的值
{
    //if_flip[i]:=i~i+1需要翻转就是1,否则就是0
    int sum = 0, res = INT_MAX;

    memset(if_flip, 0, sizeof(if_flip));
    res = min(res, get_step(0));
    memset(if_flip, 0, sizeof(if_flip));
    res = min(res, get_step(1));

    return res;
}

int get_step(int sum)//关键问题就是第一个要不要翻,如果要翻那就是0,否则就是1
{
    int i, res = sum; if_flip[1] = sum;
    for (i = 2; i <= 20; i++)
    {
        if ((sum + bowls[i - 1]) % 2 == 1)
        {
            res++;
            if_flip[i] = 1;
        }
        sum += if_flip[i];
        sum -= if_flip[i - 2];
    }
    if ((bowls[20] + sum) % 2 == 1)
        return INT_MAX;
    else return res;
}

  技术分享

  

以上是关于Greedy:The Water Bowls(POJ 3185)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3185 The Water Bowls 高斯消元

poj 3185 The Water Bowls

POJ 3185 - The Water Bowls

The Water Bowls [POJ3185] [开关问题]

water和waters的区别

[原]导入OpenStreetMap海图数据,并在GeoServer上发布