程式設計思維與實踐 Week12 作業C 區間DP

2021-10-05 23:20:58 字數 1316 閱讀 1507

輸入m,輸入n。後面跟著輸入n個ai 。

輸出最大和。

樣例:

輸入:

1 3 1 2 3

2 6 -1 4 -2 3 -2 3

輸出:6

8

考慮狀態dp[i][j],表示在選取第j個數的時候,前面的數分成i組的最大和。狀態轉移方程為:

dp[i]j=max,其中dp[i][j-1]表示前面j-1的已經分為i組了,加入a[j]與其相連,沒有改變組數。dp[i-1][k],表示在前面的k的數的時候,分為了i-1組,再加入a[j]即又多加入了一組。考慮到前面的i-1組,每組最少乙個數,故k的範圍i-1到j-1。初始可將dp[i][j]全置為0。但考慮到n為1e6,開個二維陣列的空間太大。然後每一輪更新的的時候,只用到了dp[i][j]和dp[i-1][j],即只需要兩個陣列即可。然後根據前面的狀態轉移方程,分別將dp[i]j用dpi2,dp[i-1]用dpi1來表示。即每一輪用dpi1記錄下上一輪的資料。(即使跟著原來的轉移方程變化,也是很艱難。。)需要用乙個變數每次記錄下更新後的dpi2[j],由狀態轉移方程可以知道下一輪會用到此時的dpi1[j],即dp[i-1][j-1]。由dp[i-1]知道,這個值還是用的上一輪的。所以如果再得到dpi2[j]的時候,立即更新給dpi1,就會在下一輪被用到,即使用了錯誤的值。然後就是k的遍歷,在這裡每次迴圈中記錄下的都是當前的max,故可以省去k的遍歷,即直接使用j-1。

線性規劃雖然**不長,真的巨難。。。很難想到,然後就算知道了狀態和轉移方程,迴圈怎麼寫也是個頭疼的地方,然後有的題,資料大,還得把二維的狀態壓縮。然後因為是壓縮了,所以得手動更新記錄資料,然後因為有前後兩個維度的變化,然後資料在什麼時候也得考慮清楚。我太難了。

#include 

#include

#include

#include

using namespace std;

int m,n;

int a[1000010]

;int dpi1[1000010]

; //dp[i-1]

[j]int dpi2[1000010]

; //dp[i]

[j]const int inf=-1e8;

int main(

) memset(dpi2,0,sizeof(dpi2))

; memset(dpi1,0,sizeof(dpi1));

int result;

for(int i=1; i<=m;i++)

} cout<}return 0;

}

Week12作業 必做題

a給出n個數,zjm想找出出現至少 n 1 2次的數,現在需要你幫忙找出這個數是多少?input 本題包含多組資料 每組資料報含兩行。第一行乙個數字n 1 n 999999 保證n為奇數。第二行為n個用空格隔開的整數。資料以eof結束。output 對於每一組資料,你需要輸出你找到的唯一的數。實現 ...

程式設計思維與實踐 Week2 作業

b題 倒水問題 bfs 東東有一張地圖,想通過地圖找到妹紙。地圖顯示,0表示可以走,1表示不可以走,左上角是入口,右下角是妹紙,這兩個位置保證為0。既然已經知道了地圖,那麼東東找到妹紙就不難了,請你編乙個程式,寫出東東找到妹紙的最短路線。input 輸入是乙個5 5的二維陣列,僅由0 1兩數字組成,...

程式設計思維與實踐 Week3 作業

b 區間選點 貪心 c 區間覆蓋問題 貪心 給出n個正數,從其中選出k個數,使其總和為s,問 有多少種選數方案?input 第一行是正數t t 100 表示測試的組數。每一組都輸入兩行,第一行是三個整數n,k,s,第二行是n個正整數。output 每一組輸出結果佔一行,為方案的數目。sample i...