洛谷p1373 小a和uim之大逃離

2021-09-11 16:59:17 字數 1189 閱讀 7377

題目大意:小a和uim在乙個n*m的矩陣內,矩陣的每乙個格仔有魔液,小a和uim各有乙個魔瓶,只能向下或者向右走,逃離的要求是:最後一步由uim走到且小a和uim魔瓶內的魔液等量。魔液量要%(k+1) (題意)。可以從任何一點開始,問有多少種逃離方法。

先從重疊子問題開始思考狀態,對於每乙個格仔i,j,可以是小a走到,也可以是uim走到,他們的魔液分別為a,b。第一步想到用dp[i][j][a][b][k] 來儲存這個狀態的方法數。定義這個狀態的意思是走到 i,j位置,魔液量分別為a,b, 該位置是由小a ( k ==0 ) 走到或uim ( k == 1 ) 走到的方法數。這樣定義沒問題但是會mle。

用魔液量的差值代替魔液量,優化一維,dp變成四維,可行。

思考乙個問題,差值是有負值的:dp陣列本來就是用來儲存狀態的解,只要對負值做乙個對映,使它對應到乙個正值,仍然可以不漏任何解而求出正解。

接下來思考轉移方程:由於只能向下或者向右走,很容易得到轉移方程。

接下來思考邊界狀態和**寫法:因為起點可以從任意一點開始,且第一步是小a先走,得出初始狀態:

dp[i][j][a[i][j]%(k+1)][0]=1;

那麼如何遞推更新呢?更新時不能遺漏任何乙個狀態。由於i=1.j=1這個位置,是不能由其他狀態走到的,我們可以以這個位置為起始位置,列舉這個位置的所有狀態為起始狀態,更新其他點的狀態。

方便思考就用刷表法寫了,刷表法是用已知狀態更新未知狀態,不需要過多思考邊界問題。在有些問題裡要對當前狀態進行特判judge(),避免用不合法狀態來更新合法狀態得到錯誤解。

#include

using

namespace std;

#include

#include

const

int mod=

1e9+7;

int n,m,k;

int dp[

810]

[810][

17][2

];int a[

810]

[810];

intmain()

else}}

res=

(res+dp[i]

[j][0]

[1])

%mod;}}

printf

("%d\n"

,res)

;}

洛谷 P1373 小a和uim之大逃離

小a和uim來到雨林中探險。突然一陣北風吹來,一片烏雲從北部天邊急湧過來,還伴著一道道閃電,一陣陣雷聲。剎那間,狂風大作,烏雲布滿了天空,緊接著豆大的雨點從天空中打落下來,只見前方出現了乙個披頭散髮 青面獠牙的怪物,低沉著聲音說 呵呵,既然你們來到這,只能活下來乙個!小a和他的小夥伴都驚呆了!瞬間,...

洛谷P1373 小a和uim之大逃離

我好弱啊,根本做不出啊 我開始懷疑我學了動規沒.首先瓶子容量要 然後小a和uim是一起走的,只是輪流吸魔液而已。開乙個陣列f i j k p 表示在 i,j 格仔處,二人魔液相差k,是第p個人吸。那麼uim吸魔液可以看成是小a扔掉一些魔液。bob表示瓶子容量,得到狀態轉移方程 f i j k 0 f...

洛谷 P1373 小a和uim之大逃離 dp

給你乙個n m的矩陣,每個格仔有乙個魔法值,小a和小b一起只能向右或者向下走,每次交替著吸取魔法,因為他們還修煉道術,所以只要是體內魔法值超過了k就會重新進行新的迴圈。每次都是小a先吸,可以從任何格仔開始,問你當小b吸完魔法能量以後,小a小b能量相等的機會為多少。一開始沒看清楚題,然後設了個f i ...