第十二章 dp

2021-10-21 09:53:27 字數 4337 閱讀 3064

動態規劃策略

將原始問題拆分為多個子問題,將子問題結果記錄,方便復用子問題的解

遞迴 記憶化 遞推 是動態規劃的一體兩面,本質都是一樣的;遞推減少了呼叫次數,空間上還能優化,一般選擇遞推方式

//遞迴+記憶化

int memo[maxn]

;//將o(2^n) > o(n)

intfibonacci

(int n)

//遞推

int fib[maxn]

;int

fibonacci

(int n)

return fib[n]

;}

1,-2,3,4,-10,6

看以某個元素作為尾的最大連續子串行之和

f

(j)= max

long

long dp[maxn]

;fill

(dp,dp + maxn,-1

);for(

int i =

0;i < n;

++i)

//最後還得遍歷dp選出最大值

o

(n^2

)for

(int i =

0;i < n;

++i)

}

f(i,j) 表示以下標 i 結尾的序列a和下標 j 結尾的序列b 的最長公共子串行

int dp[maxn]

[maxm]

,falg[maxn]

[maxm]

;string str1,str2;

cin >> str1 >> str2;

for(

int i =

0;i <= str1.

size()

;++i)}}

void

print

(int i,

int j)

題目描述

北大網路實驗室經常有活動需要叫外賣,但是每次叫外賣的報銷經費的總額最大為c元,有n種菜可以點,經過長時間的點菜,網路實驗室對於每種菜i都有乙個量化的評價分數(表示這個菜可口程度),為vi,每種菜的**為pi, 問如何選擇各種菜,使得在報銷額度範圍內能使點到的菜的總評價分數最大。 注意:由於需要營養多樣化,每種菜只能點一次。

輸入描述:

輸入的第一行有兩個整數c(1 <= c <= 1000)和n(1 <= n <= 100),c代表總共能夠報銷的額度,n>代表能點菜的數目。接下來的n行每行包括兩個在1到100之間(包括1和100)的的整數,分別表示菜的》**和菜的評價分數。

輸出描述:

輸出只包括一行,這一行只包含乙個整數,表示在報銷額度範圍內,所點的菜得到的最大評價分數。

示例1輸入

90 4

20 25

30 20

40 50

10 18

40 2

25 30

10 8

輸出

9538

#include

using

namespace std;

const

int maxn =

1000+10

;const

int maxm =

100+10;

int dp[maxm]

[maxn]

;int weigh[maxm]

;int value[maxm]

;int

main()

}}cout << dp[n]

[c]<< endl;

}}

壓縮空間

for

(int i =

1;i <= n;

++i) cin >> w[i]

>> v[i]

;dp[0]

=0;for

(int i =

1;i <= n;

++i)

}

0

-1揹包狀態轉移方程

dp[i]

[j]=

max(dp[i -1]

[j],dp[i -1]

[j - weigh[i]

]+ value[i]);

完全揹包狀態轉移方程為

dp[i]

[j]=

max(dp[i -1]

[j],dp[i]

[j - weigh[i]

]+ value[i]);

由於dp[i]

[j]的值僅依賴於dp[i-

1]和dp[i] 因此正向更新一維陣列即可,因為dp[i]

[j] 是原本的dp[i-1]

[j]

dp[i -1]

[j - weigh[i]

] 更新之後(j正向遍歷)就是dp[i]

[j-weigh[i]

]+ value[i]);

完全揹包核心**

for(

int i =

0;i <= n;

++i)

}

將多數量的物品繫結成2de冪次個數和乙個剩下的;然後構建新的weigh 和value;剩下的和0-1揹包一樣

#include

#define max(a,b) a > b ? a : b

using

namespace std;

const

int maxn =

100+10;

const

int maxm =

100+10;

int w[maxm]

;int v[maxm]

;int num[maxm]

;int neww[maxm *20]

;int newv[maxm *20]

;int dp[maxn]

;int

main()

if(num[i]

>0)

}for

(int i =

0;i <= n;

++i) dp[i]=0

;for

(int i =

1;i <= number;

++i)

} cout << dp[n]

<< endl;

}}

輸出字典序較小的那個解

#include

#include

using

namespace std;

const

int maxn =

1e4+10;

const

int maxm =

1e2+10;

int dp[maxm]=;

bool choice[maxn]

[maxm]

;bool flag[maxn]

;int w[maxn]

;bool

cmp(

int a,

int b)

intmain()

else choice[i]

[j]=

false;}

}if(dp[m]

!= m)

printf

("no solution");

else

else flag[i]

=false

; i--;}

for(

int i = n;i >=1;

--i)}}

}

#include

#include

using

namespace std;

intmain()

if(right - left -

1> ans) ans = right - left -1;

}for

(int i =

0;i < str.

size()

;++i)

if(right - left -

1> ans) ans = right - left -1;

} cout << ans;

}

第十二章 檔案

文字檔案 文字檔案是一種由若干字元構成的檔案,可以用文字編輯器進行閱讀或編輯。以txt py html等為字尾的檔案都是文字檔案。2.二進位制檔案 二進位制檔案一般是指不能用文字編輯器閱讀或編輯的檔案。以 mp4 png等為字尾的檔案都是二進位制檔案,如果想要開啟或修改這些檔案,必須通過特定軟體進行...

第十二章 異常

一 異常的概念 錯誤 編譯器 異常 執行期,程式沒有正常按照期望執行 異常產生時,在對應位置產生異常型別物件,程式 暫停 如果上下文有異常處理程式,對應處理 沒有則 異常向上傳播 報錯退出 異常向上傳播 如果異常在函式中產生,會傳播給函式的呼叫者 如果異常在模組的頂級位置,會傳播給引用該模組的模組 ...

第十二章 事件

檔案事件分為寫事件 ae writable 和讀事件 ae readable 採用i o復用程式監聽多個套接字,根據套接字當前執行的任務關聯事件處理器。當乙個套接字準備好執行應答 讀取 寫入 關閉操作時,會產生對應的檔案事件,檔案事件分派器會將檔案事件交給對應的事件處理器。同一時刻可能有多個套接字準...