• codeforces Flipping Game 题解


    版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/。未经本作者同意不得转载。 https://blog.csdn.net/kenden23/article/details/24862445

    Iahub got bored, so he invented a game to be played on paper.

    He writes n integers a1, a2, ..., an. Each of those integers can be either 0 or 1. He's allowed to do exactly one move: he chooses two indices i and j (1 ≤ i ≤ j ≤ n) and flips all values ak for which their positions are in range[i, j] (that is i ≤ k ≤ j). Flip the value of x means to apply operation x = 1 - x.

    The goal of the game is that after exactly one move to obtain the maximum number of ones. Write a program to solve the little game of Iahub.

    Input

    The first line of the input contains an integer n (1 ≤ n ≤ 100). In the second line of the input there are n integers:a1, a2, ..., an. It is guaranteed that each of those n values is either 0 or 1.

    Output

    Print an integer — the maximal number of 1s that can be obtained after exactly one move.

    Sample test(s)
    input
    5
    1 0 0 1 0
    
    output
    4
    本题由于数据量小,能够使用暴力法,时间效率是O(n^3)

    可是这里巧用最大子段和的思想。能够把时间效率降到O(n)

    思想:

    1 想使用一个新的数列,计算连续出现了多少个1和连续出现了多少个零

    2 求这个新数列的最大子段和

    3 Flip最大子段中的 0 和 1,

    4 计算出结果

    比暴力法复杂非常多了,可是时间效率却提高了三个档次。

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    void FlippingGame()
    {
    	int n, a;
    	cin>>n;
    	vector<bool> vbn(n);
    	for (int i = 0; i < n; i++)
    	{
    		cin>>a;
    		vbn[i] = a;
    	}
    	vector<int> ans;
    	int c = 1;
    	for (int i = 1; i < n; i++)
    	{
    		if (vbn[i] == vbn[i-1]) c++;
    		else
    		{
    			if (vbn[i-1]) ans.push_back(-c);
    			else ans.push_back(c);
    			c = 1;
    		}
    	}
    	if (vbn.back()) ans.push_back(-c);
    	else ans.push_back(c);
    
    	//求最大子段和思想
    	int stTmp = 0, st = ans.size(), end = ans.size(), maxVal = 0, sum = 0;
    	for (unsigned i = 0; i < ans.size(); i++)
    	{
    		sum += ans[i];
    		if (sum > maxVal)
    		{
    			st = stTmp;
    			maxVal = sum;
    			end = i;
    		}
    		if (sum <= 0) 
    		{
    			sum = 0;
    			stTmp = i+1;
    		}
    	}
    
    	int nums = 0;
    	for (int i = 0; i < ans.size(); i++)
    	{
    		if (ans[i] < 0) nums += ans[i];
    	}
    	if (maxVal > 0) cout<<maxVal - nums;
    	else cout<<-(ans.front()+1);
    }



  • 相关阅读:
    python读写excel利器:xlwings 从入门到精通
    认识--类 ( Class ) 面向对象技术
    python 平均值/MAX/MIN值 计算从入门到精通
    python读写word文档 -- python-docx从入门到精通
    【模板】KMP算法
    【模板】主席树
    C语言第一次博客作业
    C语言--第0次作业
    Chapter5:语句
    Chapter4:表达式
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10668455.html
Copyright © 2020-2023  润新知