算法導論隨筆 (一)

算法導論隨筆 (一)

高中的時候曾經看過同窗拿這本書做參考。當時翻閱的時候第一反應是本身確定看不下去,第二反應是內容太多了對於OI應該性價比不是很高。ios

固然,此書意義非凡,不是OI能衡量的,如今剛剛放假,因而計劃有目的地通讀,固然第一遍閱讀,目標主要是掌握要點,深度方面必然還須要以後補漏,這裏僅記錄在閱讀中本身較爲有價值的思考。算法


#### 最大子段和相關
- 在以前的校賽中,我記得有一個豬肉買賣問題:
  • 給出一個序列表明天天的豬肉價格,咱們能夠選擇在某天買入而後在以後某天賣出,求最大收益。數組

  • 而經典的最大子段和問題是,在序列中選取一段連續子序列的和,求這個最大和。

    spa

  • 在讀算法導論以前我沒有將這兩個問題聯繫到一塊兒,儘管問題簡單,可是這一點也要想到:兩問題本質是同樣的。將最大子段和問題中的序列求一遍前綴和,以後原問題就轉化爲了在前綴和數組上的豬肉問題。

    code

  • 轉化後重作水題:luogu1115 最大字段和get

  • 代碼:string

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n;
int main ()
{
	scanf("%d", &n);
	long long minn = 0;//前綴和最小值
	long long su = 0;  //前綴和變量
	long long ans = -9999999999; //答案
	for (int i = 1; i <= n; i++)
	{
		long long xx;
		scanf("%lld", &xx);
		ans = max(ans, xx);
		su += xx;
		if (minn > su)
		{
			minn = su;
		}
		else
		{
			ans = max(ans, su - minn);
		}
	}
	printf("%d\n", ans);
	return 0;
}

  • 繼續擴展水題:NOIP2013/2018 積木大賽

    it

    • 不管是積木大賽仍是鋪設道路,兩道題都是一個作法,就是豬肉問題的擴展——原先只能買一次賣一次,如今能買賣任意次,求最大收益

    • 反向轉化豬肉問題爲最大字段和問題:將序列當作前綴和數組,而且進行還原數組操做。

    • 問題就轉化爲:在獲得的數組上選取任意多的不重疊的子段和相加,求最大和,也就是把全部正數加起來就能夠了。

  • 轉化後重作水題:NOIP2013/2018 積木大賽io

  • 代碼:class

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
long long x, y, co = 0;
int main()
{
    scanf("%d", &n);
    scanf("%lld", &x);
    co = x;
    for (int i = 1; i < n; i++)
    {
        scanf("%lld", &y);
        if (y > x)//x爲sum[i - 1],y爲sum[i] y - x也就是還原a[i]
        {
            co += y - x;
        }
        x = y;
    }
    printf("%lld", co);
    return 0;
}
相關文章
相關標籤/搜索