HDU 1565 方格取數 1 (狀壓DP)

2021-06-26 18:07:19 字數 1297 閱讀 3657

problem description

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

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

input

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

output

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

sample input

3

75 15 21

75 15 28

34 70 5

sample output

188

ps:**)

對於每乙個數字,或取或不取,記1為取該數,0為不取該數,對於每行的數來說,

它的狀態就可以用乙個二進位制的數來描述,對於第一行,若果我們取75,21,

我們就可以用二進位制的5來描述,即101,因為取的數所在的2個格仔不能相鄰,

所以每一行的二進位制數不能有相鄰的1,再來看列,相鄰的兩行不能有相鄰的,

對於兩個二進位制,也就是兩個數相與(&)為0,這樣就可以得到當前的行和上一行的關係,

dp[i][j] = dp[i-1][k]+tt

dp[i][j]表示第i行在j狀態,dp[i-1][k] 表示第i-1行在k狀態,

tt表示第i行在狀態k下所取數的和,當然k&j == 0

**如下:

#include #include #include using namespace std;

const int maxn = 26;

const int maxn = 18017;

int n;

int mm[maxn][maxn];

int a[maxn], dp[maxn][maxn];

int is_use(int i)//判斷這個數的二進位制是否可以作為表示不相鄰的數

tt = i%2;

i/=2;

}return 1;

}int main()

}while(~scanf("%d",&n))

memset(dp,0,sizeof(dp));

for(int i = 0; i < n; i++)

}int maxx = -1;

for(int i = 0; i < l; i++)//先算第一行}}

printf("%d\n",maxx);

}return 0;

}

HDU 1565 方格取數 1 狀壓DP

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

HDU 1565 方格取數 1 狀壓dp

解題思路 dp i j 代表到第i行的第j個狀態所能得到的最大的和,可以先處理一行沒有兩個相鄰的滿足條件的狀態。然後把每行每個狀態的和都算出來,狀態轉移的條件是當前這行第j個狀態與上一行的第k個狀態想與為0,即沒有相鄰的,那就能更新dp i j dp i j max dp i j dp i 1 k ...

HDU 1565 方格取數 1

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