URAL 1225 Flags 簡單DP,一重迴圈

2022-08-02 05:09:14 字數 1632 閱讀 3946

題意:

視窗可放n面紅藍白三種旗,規定同色不相鄰,藍在紅白之間。共有多少種放置方法。

思路:設dp[i][j]表示有i面旗,第i面旗填顏色j(j=01表示紅白)時的總數,第i面填j色時,i-1可以填1-j(紅白相間)或者藍色,兩種填法的計算:

(1)填1-j時有dp[i-1][1-j]種   

(2)填藍色時i-2和i要填紅白色才能將i-1的藍色包圍,即i-2要填1-j,共dp[i-2][1-j]種

所以,狀態轉移方程為dp[i][j]=dp[i-1][1-j]+dp[i-2][1-j]。答案是dp[n][1]+dp[n][0]。

空間優化:

每一輪迴圈都要計算

dp[i][0] = dp[i-1][1]+dp[i-2][1]

dp[i][1] = dp[i-1][0]+dp[i-2][0]

兩式相加得:(dp[i][0] + dp[i][1]) = (dp[i-1][0]+ dp[i-1][1]) + (dp[i-2][0]+dp[i-2][1])

兩兩結構相同,去掉第二維,dp[i] 表示前i面旗的放置方法總數,第i面旗可以填紅白色。

由上面的方程得:dp[i] = dp[i-1] + dp[i-2]

直接給dp[i]分類很快,就是湊題解字數時,發現這種降維的方法,和揹包的降維不一樣。

狀態轉移分析:

第i面紅色,i-1面白色:dp[i-1]是i-1填紅白色的總數,紅白各一半,白色有dp[i-1]/2種

第i面紅色,i-1面藍色:i-2必須是白色,則有dp[i-2]/2種

第i面白色,i-1面紅色:同第一種,有dp[i-1]/2種

第i面白色,i-1面藍色:同第二種,有dp[i-2]/2種

四個加起來得到dp[i]。

初始化:

dp[i]依賴於前兩個,所以至少要提供兩個連續的dp[i],可以是dp[0] dp[1]或dp[1] dp[2]

演算法步驟:

步驟1:初始化為dp[i]=0,dp[1]=2

步驟2:遞推求dp[i],答案是dp[n]

演算法複雜度:

初始化和遞推都是乙個迴圈,時間複雜度o(n),空間複雜度o(n)

**:

#include const

int max_n = 46

;long

long

intcnt[max_n];

intmain()

突然想到前面那個完全揹包的輸入,第i個物品用完就不用了,不用用陣列儲存。

這道題只要維護三個值dp[i] dp[i-1] dp[i-2]就可以了,也就是

c = a +b; 

b =a;

a = c; -> a+b未更新

就是a = a +b;

b = a – b; //

(a舊值+b)-b

維護兩個變數就行了ooo ,迴圈用while連for裡面的區域性變數也省了,**好短

演算法步驟見**,main函式四行,一行輸入,一行計算,一行輸出,一行return 0

**:

#include int

n;long

long a=2,b=0; //

a=[1] b=a[0]

intmain()

1225 水王爭霸

水王爭霸 time limit 1000ms memory limit 65536k total submit 2 accepted 0 description 為了豐富校園網路生活,學校 bbs 舉行了一次水王爭霸賽。比賽開始後,選手們瘋狂灌水,都想爭取到水王這個榮譽稱號。但學校的 bbs 是如此...

1225 八數碼難題

時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題解檢視執行結果 description yours和zero在研究a 啟發式演算法.拿到一道經典的a 問題,但是他們不會做,請你幫他們.問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留...

1225 八數碼難題

題目描述 description yours和zero在研究a 啟發式演算法.拿到一道經典的a 問題,但是他們不會做,請你幫他們.問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布...