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