HDU 1565 方格取數 1

2021-08-27 02:53:50 字數 1314 閱讀 2684

hdu-1565-方格取數(1)

我的第乙個狀態壓縮dp

給你乙個n*n的格仔的棋盤,每個格仔裡面有乙個非負數,從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大 3

75 15 21

75 15 28

34 70 5

188對於每乙個數字,或取或不取,記1為取該數,0為不取該數,對於每行的數來說,它的狀態就可以用乙個二進位制的數來描述,對於第一行,若果我們取75,21,我們就可以用二進位制的5來描述,即101,因為取的數所在的2個格仔不能相鄰,所以每一行的二進位制數不能有相鄰的1,再來看列,相鄰的兩行不能有相鄰的,對於兩個二進位制,也就是兩個數相與(&)為0,這樣就可以得到當前的行和上一行的關係,dp[i][j]=dp[i-1][k]+sum(j)

dp[i][j]表示第i行在j狀態,dp[i-1][k] 表示第i-1行在k狀態,sum(j)表示第i行在狀態k下所取數的和,當然k&j==0

#include#include#include#include#includeusing namespace std;

int num[21];

int k,st[18800]; //共有k中狀態

int dp[2][18800];

int map[25][25];

int n;

int max(int x,int y)

void init1() //初始化num,n位數2進製數最多有num[n]種

int judge(int x)

return 1;

}void init2()

int main()

for(i=0;i=num[n]) //n位數2進製數最多有num[n]種

break;

for(j=0;jmax)

max=dp[0][i];

}for(i=1;i=num[n])

break;

temp=0;

for(h=0;h=num[n])

break;

if(!(st[h]&st[j]))

dp[1][j]=max(dp[1][j],dp[0][h]+temp);

max=max(max,dp[1][j]);}}

for(j=0;jnum[n])

break;

dp[0][j]=dp[1][j];

dp[1][j]=0;}}

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

}system("pause");

return 0;

}

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...

hdu 1565 方格取數 1

這個題網上很多人都說用狀態壓縮dp來做,我就是覺得狀態壓縮dp有點那麼理解不上啊,不過如果這個題吧相鄰的兩個格仔連起來,那不就是求最大權獨立點集嗎?奮戰了三天,我的第一道最大流題目終於寫出來了,高興啊!include include include include include include i...