近期的DP題

2021-09-06 15:29:24 字數 1204 閱讀 4310

1:

找出n個數中最長的等差數列

例:1    3     5     6     8     9     10     12     13     14

三項以上的等差子數列包括:

1 3 5

1 5 9 13

3 6 9 12

3 8 13

5 9 13

6 8 10 12 14

其中6 8 10 12 14最長,長度為5

首先,排序是很容易想到的,但排序後該怎麼做呢?

我們看一下等差數列的性質,發現兩個不同的等差數列,首項和公差總有乙個不同

而公差可以根據首項與第2項的差值得到

因此設f[i][j]為首項為a[i],第2項為a[j]的最長長度

若k為第3項,則f[i][j]=f[j][k]+1(從後往前轉移!)

在根據等差數列的性質,a[j]*2=a[i]+a[k]

因此for迴圈列舉j,接著從j-1和j+1開始列舉i和k,將滿足條件的轉移即可

2:將n個數分成互不相交的m個字段和,且總和最大(若m小於正數個數,輸出正數的總和)

例:-2    11    -4      13     -5        6        -2

分2段,11,-4,13一段,6一段,總和26

設f[i][j]表示表示前 j 項所構成 i 子段的最大和,且必須包含著第j項

則分2種情況:

一:f[ i ][ j ] = f[ i ] [ j-1 ] + a[ j ] ,即把第j項融合到第 j-1 項的子段中,子段數沒變

二:f[ i ][ j ] = max(f[ i-1 ] [ k ]) + a[ j ],(i-1<= k< j )

考慮到時間,可以把f[ i-1 ][ k ]用乙個一維陣列記錄,兩重迴圈即可

3:有n個數,它們的範圍在1到a[ i ]之間,問怎麼安排能使所有相鄰兩數的絕對值之和最大

由於要是差值最大,因此每個數一定為1或a[ i ]

設f[ i ][ 0 ]為i選1,f[ i ][ 1 ]為i選a[ i ]

f[1][0] = f[1][1] = 0

f[i][0] = max(f[i-1][0], f[i-1][1] + abs(1-a[i-1]))

f[i][1] = max(f[i-1][1] + abs(a[i]-a[i-1]), f[i-1][0] + abs(a[i]-1))

複雜度為o(n)

近期寫題遇到的函式

1.ceil函式 用法 double ceil double x 功能 返回大於或者等於指定表示式的最小整數 標頭檔案 cmath math.h 2.stol函式 用法 long stol const string str,size t idx 0,int base 10 str 要轉換的字串行。i...

近期刷題的c語言總結。

首先是三個數學函式。函式名 floor 功 能 下捨入,返回小於或者等於指定表示式的最大整數 說明 返回x的下限,如74.12的下限為74,74.12的下限為 75。返回值為float型別。用 法 double floor double x 標頭檔案 math.h 函式名 ceil 用 法 doub...

近期刷題的c語言總結。

首先是三個數學函式。函式名 floor 功 能 下捨入,返回小於或者等於指定表示式的最大整數 說明 返回x的下限,如74.12的下限為74,74.12的下限為 75。返回值為float型別。用 法 double floor double x 標頭檔案 math.h 函式名 ceil 用 法 doub...