演算法小講堂 動態規劃!之牛客練習賽41 B題

2021-09-12 01:16:47 字數 1792 閱讀 5549

說來實在慚愧,已經很久沒有更新部落格了。(反正也沒人看-.-//偷笑)

那麼今天就更新一道dp型別的題目。

所謂:dp**好,好到頭髮少。

另外需要補充的一點是呢,這題我在時限內並沒有寫出來,可謂菜的開花(直接開花)。但是我覺得這個dp的手法十分有用,所以我就很厚臉皮更上了一期,當然也會盡量把思路說的的比較詳細啦。

看題!!

牛客練習賽41-b題

很明顯的是一道dp題,但是狀態轉移方程怎麼推,dp陣列又怎麼開,完全沒有思路。

一剛開始以為是倒著dp,而且肯定時按次數dp的,於是先是認為確定距離最後乙個數的偶數個數變化成為-666:

比如10個資料的話,那就是10,8,6,4,2轉變成-666,因為後面一定是偶數個時才能不變換符號。這樣就找到了子問題,但是,問題就來了,dp陣列怎麼辦,涼涼。

所以,上面的思路全是廢話,從這裡看起:

因為300*666(總和)資料並不算很大,可以直接用陣列記錄下來和,陣列的第乙個維度的大小就是300 * 666的兩倍,兩倍,因為有正負情況。另外還可以用滾動陣列減小空間的使用,注意取mod

(下面有介紹滾動陣列是個啥

狀態轉移方程:dp[i][maxn+j] = dp[i-1][maxn+j-a[i]]+dp[i-1][maxn-j];
#include

using namespace std;

const

double eps =

1e-6

;const

int inf=

1e9;

const

int maxn=

300*

700;

//比300*666略大就行

const

int mod =

1e8+7;

#define max_n 100007

#define max_m 10001

#define ll long long

int dp[2]

[maxn*2]

;int a[

301]

;int

main()

}}printf

("%d\n"

,dp[n%2]

[maxn-

666]);

return0;

}

同樣是牛客練習賽的40場,a題滾動陣列簡單理解就是通過不斷迴圈利用陣列,來減少空間的使用,這種思想其使用的還是比較多的。

最常見的有一種就是斐波那契數列的實現 :

int a=

1,b=

1,c=a+b;

for(

int i=

0;i<

100;i++

)

斐波那契額的遞推公式f[i] = f[i-1]+f[i-2];所以實際上需要的數只有三個,就是上面**中的a,b,c。

那麼有些朋友可能會說了:

「哦,我知道了,那上面這個狀態轉移方程(dp[i][maxn+j] = dp[i-1][maxn+j-a[i]]+dp[i-1][maxn-j];)也是有兩個相加的,也可以變成a,b,c三個數」。

不行!,為啥呢,因為一維上的下標是不確定的,但是從二維角度上來看,得到下一行的所有數值,只需要前面一行的所有數就行了,所以可以壓縮成只有兩行的二維陣列。不知道這樣大家懂了沒有。

牛客網練習賽7 購物 動態規劃

題意 在遙遠的東方,有一家糖果專賣店。這家糖果店將會在每天 一些糖果,它每天都會生產出m個糖果,第i天的第j個糖果 為c i j 元。現在的你想要在接下來的n天去糖果店進行選購,你每天可以買多個糖果,也可以選擇不買糖果,但是最多買m個。因為最多隻生產m個 買來糖果以後,你可以選擇吃掉糖果或者留著之後...

牛客練習賽9

時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 珂朵莉想每天都給威廉送禮物,於是她準備了n個自己的本子 她想送最多的天數,使得每天至少送乙個本子,但是相鄰兩天送的本子個數不能相同 珂朵莉最多送幾天禮物呢 第一行乙個整...

牛客練習賽15

時間限制 c c 2秒,其他語言4秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 第一次期中考終於結束啦!沃老師是個語文老師,他在評學生的作文成績時,給每位學生的分數都是乙個小於10的非負小數。amy 8.99999999999999999999...