HDU 1565 方格取數(簡單狀態壓縮DP

2022-05-01 11:51:09 字數 1243 閱讀 9332

對於每乙個數,取或者不取,用0表示不取,1表示取,那麼對於每一行的狀態,就可以用乙個二進位制的數來表示。比如5的二進位制為101,就表示取第乙個數,不取第二個數,取第三個數。

將符合要求的狀態儲存下來,什麼是符合要求的呢?即二進位制數中不存在相鄰的1(110,011都是不符合要求的)。可以用移位並按位與的辦法來判斷,舉個例子:110左移一位為011 ,110&011 = 1,不符合要求;101左移一位為010,101&010=0,符合要求,這是判斷同一行時的方法。

判斷上下兩行,只需將上下兩行的狀態按位與即可。(ps:在紙上寫寫,和容易就能看出來)

然後列舉每一行的狀態和上一行的狀態,找出不與上乙個狀態衝突的情況,然後計算,選擇當前狀態的最大值

ac

#include #include 

#include

#include

using

namespace

std;

int status[20000];//

存狀態int mp[25][25

];int d[25][20000];//

d[i][j]表示第i行第j種狀態時的最大和(這時的最大和是1~i行所能取得的最大和)

intn;

///將符合要求的狀態儲存下來,即沒有兩個一相鄰的情況

int init(int

n)///

計算該狀態的和

int cal(int x,int

t)

return

sum;

}int

main( )

int m = init(1

//初始化,找到狀態一有多少

memset(d,0,sizeof

(d));

for(int i=0 ; i)

for(int j=0 ; j)

scanf("%d

",&mp[i][j]);

for(int i=0 ; i)

d[0][i]=cal(0

,status[i]);

for(int i=1 ; i///

第i行 }

}int ans=0

;

for(int i=n-1 , j=0 ; j)

ans=max(d[i][j],ans);

printf(

"%d\n

",ans);

}return0;

}

view code

HDU 1565 方格取數

第一道狀態壓縮dp,比較簡單,做得也比較暴力,不過還挺適合入門,貼個 紀念一下 include include include include include define pub push back define ll int64 using namespace std const int n 2...

HDU1565方格取數

典型的狀態壓縮dp問題。第i行的取法只受到第i 1行的影響。首先每一行的取法要相容 不能有兩個相鄰 然後相鄰行之間也要相容。將每乙個格仔看做兩種狀態,1表示取,0表示不取。這樣每一行就是乙個01串,恰好可以看做是乙個二進位制數,那麼該二進位制數對應的十進位制整數可以唯一的表示為當前第 i 行的狀態。...

HDU 1565 方格取數 1

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