最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

浙江大學(xué)《數(shù)據(jù)結(jié)構(gòu)》MOOC 編程練習(xí) 題解(一)

2022-09-16 16:27 作者:Soap_mac_tavish  | 我要投稿

01-復(fù)雜度1 最大子列和問(wèn)題

給定K個(gè)整數(shù)組成的序列{ N1, N2, ..., NK },“連續(xù)子列”被定義為{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。“最大子列和”則被定義為所有連續(xù)子列元素的和中最大者。例如給定序列{ -2, 11, -4, 13, -5, -2 },其連續(xù)子列{ 11, -4, 13 }有最大的和20?,F(xiàn)要求你編寫(xiě)程序,計(jì)算給定整數(shù)序列的最大子列和。

?

本題旨在測(cè)試各種不同的算法在各種數(shù)據(jù)情況下的表現(xiàn)。各組測(cè)試數(shù)據(jù)特點(diǎn)如下:

?

數(shù)據(jù)1:與樣例等價(jià),測(cè)試基本正確性;

數(shù)據(jù)2:100個(gè)隨機(jī)整數(shù);

數(shù)據(jù)3:1000個(gè)隨機(jī)整數(shù);

數(shù)據(jù)4:10000個(gè)隨機(jī)整數(shù);

數(shù)據(jù)5:100000個(gè)隨機(jī)整數(shù);

?

輸入格式:

輸入第1行給出正整數(shù)K (<= 100000);第2行給出K個(gè)整數(shù),其間以空格分隔。

?

輸出格式:

在一行中輸出最大子列和。如果序列中所有整數(shù)皆為負(fù)數(shù),則輸出0。

?

輸入樣例:

6

-2 11 -4 13 -5 -2

?

輸出樣例:

20

?

代碼長(zhǎng)度限制:16 KB

時(shí)間限制:50000 ms

內(nèi)存限制:64 MB

?

本題一共有四種算法:

第一種算法:

int MaxSubseqSum1(int A[], int N) {

? ? int thisSum, maxSum = 0;

??? int i, j, k;

??? for (i = 0; i < N; i++) { ?/* i是子列左端位置 */

??????? for (j = i; j < N; j++) { ?/* j是子列右端位置 */

??????????? thisSum = 0;? /* thisSum是從A[i]到A[j]的子列和 */

??????????? for (k = i; k <= j; k++) {

??????????????? thisSum += A[k];

??????????? }

??????????? if (thisSum > maxSum) {? /* 如果剛得到的這個(gè)子列和更大 */

??????????????? maxSum = thisSum; ?/* 則更新結(jié)果 */

??????????? }

??????? } ?/* j循環(huán)結(jié)束 */

??? } ?/* i循環(huán)結(jié)束 */

??? return maxSum;

}

?

從時(shí)間復(fù)雜度進(jìn)行分析,該算法使用了3個(gè)循環(huán),最高次為3,所以我們就記作T(N)=O(N3),本題測(cè)試數(shù)據(jù)中最高次有100000個(gè)數(shù)據(jù),而100000 ^ 3 = 10 ^ 15,如果每秒計(jì)算1億次,也要116天左右才能運(yùn)行出來(lái)。所以該算法效率不行。

?

算法2:

int MaxSubseqSum2(int A[], int N) {

??? int thisSum, maxSum = 0;

??? int i, j;

??? for (i = 0; i < N; i++) { ?/* i是子列左端位置 */

??????? thisSum = 0;? /* thisSum是從A[i]到A[j]的子列和 */

??????? for (j = i; j < N; j++) { ?/* j是子列右端位置 */

??????????? thisSum += A[j];

??????????? /* 對(duì)于相同的i,不同的j,只要在j – 1次循環(huán)的基礎(chǔ)上累加1項(xiàng)即可 */

??????????? if (thisSum > maxSum) {? /* 如果剛得到的這個(gè)子列和更大 */

??????????????? maxSum = thisSum; ?/* 則更新結(jié)果 */

??????????? }

??????? } ?/* j循環(huán)結(jié)束 */

??? } ?/* i循環(huán)結(jié)束 */

??? return maxSum;

}

?

從時(shí)間復(fù)雜度進(jìn)行分析,該算法使用了2個(gè)循環(huán),最高次為2,比算法1要好很多,但是當(dāng)100000個(gè)數(shù)據(jù)的時(shí)候,需要大約100秒的時(shí)間,也會(huì)超時(shí)。效率還是比較低。

?

算法3:

int Max3(int A, int B, int C) {

??? return A > B ? A > C ? A : C : B > C ? B : C;

}

?

int DivideAndConquer(int List[], int left, int right) {

??? /* 分治法求List[left]到List[right]的最大子列和 */

??? int maxLeftSum, maxRightSum;? /* 存放左右子問(wèn)題的解 */

??? int maxLeftBorderSum, maxRightBorderSum;? /*存放跨分界線的結(jié)果*/

??? int leftBorderSum, rightBorderSum;

??? int center, i;

??? if (left == right) {? /* 遞歸的終止條件,子列只有1個(gè)數(shù)字 */

??????? if(List[left] > 0) {

??????? ?????? return List[left];

????????????? } else {

???????????????????? return 0;

????????????? }

??? }

?

??? /* 下面是"分"的過(guò)程 */

??? center = (left + right) / 2; /* 找到中分點(diǎn) */

??? /* 遞歸求得兩邊子列的最大和 */

??? maxLeftSum = DivideAndConquer(List, left, center);

??? maxRightSum = DivideAndConquer(List, center + 1, right);

?

??? /* 下面求跨分界線的最大子列和 */

??? maxLeftBorderSum = 0; leftBorderSum = 0;

??? for (i = center; i >= left; i--) {? /* 從中線向左掃描 */

??????? leftBorderSum += List[i];

??????? if(leftBorderSum > maxLeftBorderSum) {

? ? ? ? ? ? maxLeftBorderSum = leftBorderSum;

? ? ? ? }

??? }? /* 左邊掃描結(jié)束 */

?

??? maxRightBorderSum = 0; rightBorderSum = 0;

??? for (i = center + 1; i <= right; i++) {? /* 從中線向右掃描 */

??????? rightBorderSum += List[i];

??????? if (rightBorderSum > maxRightBorderSum) {

? ? ? ? ? ? maxRightBorderSum = rightBorderSum;

? ? ? ? }

??? }? /* 右邊掃描結(jié)束 */

?

??? /* 下面返回"治"的結(jié)果 */

? ? return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);

}

?

int MaxSubseqSum3(int List[], int N) {

??? return DivideAndConquer(List, 0, N-1);

}

?

該算法又叫做分而治之,就是將問(wèn)題化成小塊,在小塊里進(jìn)行解決,然后再放回到大塊,這也可以說(shuō)是遞歸的一種吧,在課上,陳越老師也講過(guò),該算法的復(fù)雜度為T(mén)(n) = O(nlogn),取100000時(shí),在每秒一億次運(yùn)算的基礎(chǔ)上,可以在大約0.02秒內(nèi)得到答案,但是PINTIA上面的計(jì)算機(jī)沒(méi)那么大本事,而且這代碼量太長(zhǎng),這條先備用。

?

算法4(推薦):在線處理

int MaxSubseqSum4(int A[], int N) {

? ? int thisSum, maxSum;

? ? int i;

? ? thisSum = maxSum = 0;

? ? for (i = 0; i < N; i++) {

? ? ? ? thisSum += A[i];

? ? ? ? if (thisSum > maxSum) {

? ? ? ? ? ? maxSum = thisSum;

? ? ? ? } else if (thisSum < 0) {

? ? ? ? ? ? thisSum = 0;

? ? ? ? }

? ? }

? ? return maxSum;

}

?

該算法的時(shí)間復(fù)雜度為O(N),因?yàn)橹粓?zhí)行了一次循環(huán),當(dāng)N取100000時(shí),結(jié)果也是很快就能出來(lái)。

該題完整的AC代碼:

C:

#include <stdio.h>


int MaxSubseqSum(int A[], int N)?{

? ? int thisSum, maxSum;

? ? int i;

? ? thisSum = maxSum = 0;

? ? for (i = 0; i < N; i++) {

? ? ? ? thisSum += A[i];

? ? ? ? if (thisSum > maxSum) {

? ? ? ? ? ? maxSum = thisSum;

? ? ? ? } else if (thisSum < 0) {

? ? ? ? ? ? thisSum = 0;

? ? ? ? }

? ? }

? ? return maxSum;

}

?

int main() {

? ? int n, i;

? ? scanf("%d", &n);

? ? int a[n];

? ? for (i = 0; i < n; i++) {

? ? ? ? scanf("%lld", &a[i]);

? ? }

? ? printf("%d\n", MaxSubseqSum(a, n));

? ? return 0;

}

?

Python:

def?MaxSubseqSum(a, n):

??? thisSum, maxSum = 0, 0

??? for i in range(n):

??????? thisSum += a[i]

??????? if thisSum > maxSum:

??????????? maxSum = thisSum

??????? elif thisSum < 0:

??????????? thisSum = 0

??? return maxSum

?

?

n = eval(input())

a = list(map(int, input().split(" ")))

print(MaxSubseqSum(a, n))


本來(lái)試著用Java寫(xiě)的,但是Java太廢內(nèi)存了,還廢時(shí)間:

// Memory Limit Exceeded

import java.util.Scanner;


public class Main {

? ? public static void main(String[] args) {

? ? ? ? int n, i;

? ? ? ? Scanner javain = new Scanner(System.in);

? ? ? ? n = javain.nextInt();

? ? ? ? int a[] = new int[n + 1];

? ? ? ? for (i = 0; i < n; i++) {

? ? ? ? ? ? a[i] = javain.nextInt();

? ? ? ? }

? ? ? ? System.out.println(MaxSubseqSum(a, n));

? ? }

? ??

? ? public static int MaxSubseqSum(int A[], int N) {

? ? ? ? int thisSum, maxSum;

? ? ? ? int i;

? ? ? ? thisSum = maxSum = 0;

? ? ? ? for (i = 0; i < N; i++) {

? ? ? ? ? ? thisSum += A[i];

? ? ? ? ? ? if (thisSum > maxSum) {

? ? ? ? ? ? ? ? maxSum = thisSum;

? ? ? ? ? ? } else if (thisSum < 0) {

? ? ? ? ? ? ? ? thisSum = 0;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return maxSum;

? ? }

}


浙江大學(xué)《數(shù)據(jù)結(jié)構(gòu)》MOOC 編程練習(xí) 題解(一)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
延川县| 五原县| 漳浦县| 渑池县| 长阳| 老河口市| 福安市| 阿瓦提县| 台中县| 于都县| 泾阳县| 淳安县| 韶山市| 拉萨市| 灯塔市| 老河口市| 尼勒克县| 镇原县| 榆社县| 中牟县| 津市市| 江孜县| 出国| 河南省| 夹江县| 灵台县| 涿鹿县| 苗栗县| 凤阳县| 湖州市| 海林市| 镇宁| 色达县| 隆昌县| 福泉市| 团风县| 巢湖市| 兰坪| 泗水县| 文安县| 凌云县|