zoukankan      html  css  js  c++  java
  • Greedy:The Water Bowls(POJ 3185)

                    

                      水池

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

      这一题的:满足

        1:翻转次序不改变结果

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

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

        一开始我想着像3279那样枚举,可是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
    ", 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;
    }

      

      

  • 相关阅读:
    ES6 Promise用法讲解
    NPM使用介绍
    Docker学习系列(二):Docker三十分钟快速入门(上)
    Spring Cloud学习(一)
    胖ap和瘦ap的区别
    论网络知识的重要性
    2018 发发发发
    sikuli--前端自动化操作的神器
    更改MySQL数据库的编码为utf8mb4
    数据库mysql的常规操作
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5155387.html
Copyright © 2011-2022 走看看