Lightoj 1071 記憶化搜尋

2021-06-19 23:00:10 字數 1341 閱讀 7437

題目的意思是說:在乙個二維的方格中有一些人需要幫助,你需要從左上角走到右下角,然後再返回左上角,而且每次走的不能重複,向下的時候只能向下或向右走,返回的時候只能向上或向左走,求最多能救的人數。

這一題簡化一下就是要找兩條從左上到右下的路,且兩條路不能相交。可以用記憶化搜尋。

用dp[step][r1][r2]表示各經過step後一條路到達了第r1行,另乙個到了r2行時,繼續走所能救的最大人數,然後列是可以算出來的(step - r1, step - r2 );然後向後dfs即可,然後儲存已經找出的狀態

有一點要注意的是,我在計算dp[step][r1][r2]的時候如果 r1 == r2 (說明r1與r2位置重疊)則只加一次score 那麼最後在求max的時候一定會捨去這種情況(因為在不重疊的情況下,還能再救一部分的人)

ac**如下:

#include #include #include #include #include using namespace std;

#define max 0x3f3f3f3f

int dp[202][100][100];

int m, n;

int score[100][100];

int dfs( int step, int r1, int r2 )else

} int ans = dp[step][r1][r2];

if( ans != -1 )

if( step - r1 < n - 1 && step - r2 < n - 1 ) ans = max( ans, dfs( step + 1, r1, r2 ) );

if( r1 < m - 1 && step - r2 < n - 1 ) ans = max( ans, dfs( step + 1, r1 + 1, r2 ) );

if( r2 < m - 1 && step - r1 < n - 1 ) ans = max( ans, dfs( step + 1, r1, r2 + 1 ) );

if( r1 < m - 1 && r2 < m - 1 ) ans = max( ans, dfs( step + 1, r1 + 1, r2 + 1 ) );

ans += score[r1][step-r1];

if( r1 != r2 )

return dp[step][r1][r2] = ans;

}int main()

} memset( dp, -1, sizeof( dp ) );

cout << "case " << case++ << ": " << dfs( 0, 0, 0 ) << endl;

} return 0;

}

lightoj 1173 記憶化搜尋

題目的意思是有n個公升高不同的人,求高矮間隔排列的數目,並且依據題目的意思,隊長肯定在第乙個。然後這一題可以這樣想 a1 a2 a3 a4 a5.ak 表示已經排列好了的人,然後還有n個人 那麼用 dp n m 1 來表示 排剩下的n個人,並且這n個人中有m個人比ak高,且接下來排的第乙個人要比ak...

Lightoj 1084 記憶化搜尋(DP)

dfs cur 表示從cur開始最少能分多少組 然後next是 使cur到next最大 然後if next cur 3 if next cur 4 if next cur 5 這三個判斷是說 可以 分乙個給後面 或者分兩個給後面 或者乙個都不給後面 來組成新的小組 然後就a啦 ac 如下 inclu...

skiing 記憶化深搜

這道題就是找出一條最長連續遞減序列,並求出其長度。可以用記憶化深搜,求出每一點最長序列的長度,然後求最大值即可。如下 include includeusing namespace std const int n 105 int a n n m,n,f n n inline int max int a...