HDUOJ 1565 方格取數 1

2021-10-07 16:24:02 字數 1878 閱讀 9415

題目鏈結

給你乙個n*n的格仔的棋盤,每個格仔裡面有乙個非負數。

從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。

包括多個測試例項,每個測試例項包括乙個整數 n 和 n*n個非負數(n<=20)

對於每個測試例項,輸出可能取得的最大的和

3

75 15 21

75 15 28

34 70 5

188
典型的狀壓 dp ~

我們對每一列的取數可以用二進位制表示,有 n

nn 位顯然就是 [0,

2n

)[0,2^n)

[0,2n)

,那麼對相鄰的兩行 x,y

x,yx,

y 只需要判斷 x&y

=0

x\&y=0

x&y=

0 即可,如果等於 0

00 證明兩行無相鄰點。但此時複雜度還是太高了,我們想到一行中也不能存在相鄰點,也就是說這個數的二進位制裡不能有相鄰的 1

11,判斷只需用 x&(

x>

>1)

=0

x\&(x>>1)=0

x&(x

>

>1)

=0判斷即可,為什麼呢?因為只要二進位制中無連續的 1

11,該數與其錯一位後進行與運算一定等於 0

00,可以自己列幾個數字計算一下,這樣篩一下數後複雜度就能大幅降低,下面考慮 dp

我們用 dp[

i][j

]dp[i][j]

dp[i][

j]表示第 i

ii 行以 j

jj 作為該行狀態的最大值,cal

(i,j

)cal(i,j)

cal(i,

j)函式計算 i

ii 行以 j

jj 為狀態後的取值,那麼我們可以列舉 i−1

i-1i−

1 行所有符合條件的最大值加上 cal

(i,j

)cal(i,j)

cal(i,

j),即:dp[

i][j

]=ma

x(dp

[i][

j],d

p[i−

1][k

]+ca

l(i,

j)),

k&j=

0dp[i][j]=max(dp[i][j],dp[i-1][k]+cal(i,j)),k\&j=0

dp[i][

j]=m

ax(d

p[i]

[j],

dp[i

−1][

k]+c

al(i

,j))

,k&j

=0ac**如下:

#include

using

namespace std;

int n,a[20]

[1<<18]

,dp[20]

[1<<18]

;int num[

1<<18]

;int

cal(

int x,

int y)

return sum;

}int

main()

}}}for

(int i=

1;i<=cnt;i++

) ans=

max(ans,dp[n]

[i])

;printf

("%d\n"

,ans);}

return0;

}

HDU 1565 方格取數 1

hdu 1565 方格取數 1 我的第乙個狀態壓縮dp 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數,從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大 3 75 15 21 75 15 28 34 70 5 188對於每乙個數...

HDU1565 方格取數 1

problem description 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數。從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。input 包括多個測試例項,每個測試例項包括乙個整數n 和n n個非負數 n 20 ou...

HDU 1565 方格取數 1

problem description 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數。從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。input 包括多個測試例項,每個測試例項包括乙個整數n 和n n個非負數 n 20 ou...