HDU 5965 掃雷(dp 遞推)

2021-09-27 10:01:45 字數 1814 閱讀 9302

傳送門

掃雷遊戲是晨晨和小璐特別喜歡的智力遊戲,她倆最近沉迷其中無法自拔。

該遊戲的介面是乙個矩陣,矩陣中有些格仔中有乙個地雷,其餘格仔中沒有地雷。 遊戲中,格仔可能處於己知和未知的狀態。如果乙個己知的格仔中沒有地雷,那麼該 格仔上會寫有乙個一位數,表示與這個格仔八連通相鄰的格仔中地雷總的數量。

現在,晨晨和小璐在乙個3行n列(均從1開始用連續正整數編號)的矩陣中進 行遊戲,在這個矩陣中,第2行的格仔全部是己知的,並且其中均沒有地雷;而另外 兩行中是未知的,並且其中的地雷總數量也是未知的。

晨晨和小璐想知道,第1行和第3行有多少種合法的埋放地雷的方案。

input

包含多組測試資料,第一行乙個正整數t,表示資料組數。

每組資料由一行僅由數字組成的長度為n的非空字串組成,表示矩陣有3行n 列,字串的第i個數字字元表示矩陣中第2行第i個格仔中的數字。

保證字串長度n <= 10000,資料組數<= 100。

output

每行僅乙個數字,表示安放地雷的方案數mod100,000,007的結果。

sample input222

000sample output61

思路:剛開始覺得是狀壓dp,然後列舉了三列的狀態,一直超時,,沒想到怎麼優化,後來看了別人部落格發現,只需要列舉兩列就行了,第三列可以根據已知的這兩列算出來。。dp[i][j][k]表示第i列地雷數為j,第 i-1 列地雷數為k的情況下的方案數有多少種。

或者直接遞推,第一列的狀態確定了,後面的就都確定了。每一列地雷數為1的話有兩種放法,0或者2只有1種方法,所以只需要列舉第一列的地雷數,然後依次計算即可,時間複雜度為o(n)

dp做法:

#include

#include

#include

using namespace std;

const int n

=1e4+10

,mod =

1e8+7;

int dp[n]

[10][

10];int main()

for(int i=

2;i<=n;i++)}

int ans=0;

for(int i=

0;i<

3;i++

)for

(int j=

0;j<

3;j++)if

(i+j==

(s[n]

-'0'))

//只計算合法的方案數

ans=

(ans+dp[n]

[i][j]

)%mod;

cout<

}return0;

}

遞推做法:

#include

#include

#include

using namespace std;

const int n

=2e5+10

,mod=

1e8+7;

int num[n]

;int main()

if(j<=n||

(num[n-1]

+num[n]

!=s[n]

-'0'

)) continue;

ans=

(ans+sum)

%mod;

} cout<

}return0;

}

HDU 5965 掃雷 線性遞推

給乙個3 n的矩陣,第一行和第三行可能會有地雷,第二行沒有地雷,第二行每個格仔上都有1個數,表示在以該格仔為中心的九宮格中一共有幾個地雷。給出第二行每個格仔上的數字,問安放地雷的方案。乍一看不會。然後再仔細想想,可以發現第一列的地雷數量決定了第二列的地雷數量,而第一列和第二列的數量決定了第三列的數量...

HDU5965 掃雷 記憶化搜尋

思路 設d i j k l 為 第i個位置還有j個炸彈未放置,且 1,i 的位置有k個雷,3,i 的位置有l個雷,0 k,l 1時的方案總數,那麼i 1個位置還剩str i 1 0 k l個雷未放置,再按當前剩餘j k l個未放置的類在i 1的位置上放置 include include includ...

hdu5965掃雷(列舉 動態規劃)

原題鏈結 題目大意 給你n組資料,每組表示3 m的掃雷格仔的最中間一格的情況,現不知道第一行和第三行的情況位置,要求你求出滿足給定序列數字,在第一行和第三行放雷的情況有多少種。題解 dp 遞推列舉 我們可以知道第一列的情況最多三種 0,1,2表示第一列放雷的個數。然後從第二列往後遞推,dp i 表示...