傳紙條和方格取數(DP)

2021-09-05 10:30:28 字數 3776 閱讀 9816

輸入輸出樣例

輸入樣例#1:

3 30 3 9

2 8 5

5 7 0

輸出樣例#1:

34首先發現這可能是兩種路徑(一種是從小淵內邊,另一種是從小軒內邊),但是我們可以發現很難實現點的清零或者是路徑的儲存,而且還面對著當前的路徑是否為最優解的問題(一開始博主用的貪心)然後博主就用了取模存點的鬼畜演算法,真的難搞…… 。

因為貪心問題多多,漏洞百出,狀態過多且不好儲存,所以,我們考慮dp:因為這是兩個人,所以每種狀態中只會有兩種路徑,所以我們可以增加dp的狀態從而儲存路徑。

我們考慮用f[i

,j,k

,l]f[i,j,k,l]

f[i,j,

k,l]

表示當前乙個人到達[i,

j][i,j]

[i,j

],另外乙個人到達了[k,

l][k,l]

[k,l

]的最大好心值。

那麼,狀態轉移方程,也就可以根據二人的走法(向右,向下)進行轉移。

#include

using

namespace std;

int m,n;

int a[52]

[52];

int f[52]

[52][

52][52

];inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}voidin(

)int

main()

printf

("%d\n"

,f[m]

[n][m]

[n])

;return0;

}

其實按照上面的思路我們還可以搞一下優化,當你模擬的時候,你會驚奇地發現,橫座標和縱座標的和是一樣的,而且正好==step-1(也就是你的步數)(減一是因為我的初始位置在(1,

1)(1,1)

(1,1

)的位置上)

為什麼,博主要說如下的話呢??(在這裡博主要強烈建議一下,好好想一想)

如果按照博主的思路的話,(兩條交叉的路徑變成兩條起點相同,終點相同,卻有不一樣的路徑。)

這樣的話,模擬一下吧(a表示第一條路徑,b表示第二條路徑)(在這裡我們規定a所代表的路徑是一直向下走的,b所代表的路徑是一直向右走)當然你不信的話,你也可以模擬乙個其他的什麼

根據上面所列出的**可以發現:(xa+xb==sum-1)

因為你只能向下或者是向右,而每一步你走之後,sum的之就會增加一。(謎團解開,當然,上面都是一些廢話什麼的 )

之後,你的dp陣列就可以換一下,因為之前是用四維陣列表示四種狀態,但是現在可以用和sum來表示xa和xb,不就少了一種狀態!!!!!!

注意陣列的大小。

**如下

#include

using

namespace std;

#define maxn 52

int m,n;

int a[maxn]

[maxn]

;int f[

2*maxn]

/*這裡這裡的2*maxn十分重要*/

[maxn]

[maxn]

;inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}voidin(

)//輸入

intmain()

printf

("%d\n"

,f[n+m-1]

[n][n]);

return0;

}

以上就是傳紙條的博主的思考

其實思路都和上面是一樣的(由於博主想讓你們自己思考思考 就是博主懶 )

直接見**

#include

using

namespace std;

int n;

int ans=0;

int a[11]

[11];

int f[11]

[11][

11][11

];inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}voidin(

)}intmain()

printf

("%d\n"

,f[n]

[n][n]

[n])

;//這裡是邊界以及和上面的區別

return0;

}

啦啦啦,最後,還記得博主說的鬼畜的取模存點的鬼畜演算法嗎,其實內個鬼畜演算法是方格取數中的,主要是因為博主不會記錄狀態,於是乎,將每次取得x,y記錄到另兩個數(p,q)裡。

如:1 x=3,y=4 p=3,q=4

2 x=2,y=1 p=32,q=41

3 x=9 y=6 p=329,q=413

……這樣子的話,你的路徑就會儲存在乙個變數中。而且由於方格取數中都是1~9的數字,所以他們都是一一對應的,取出來也比較方便(這可是博主自己想出來的哦,小驕傲(^-^)v)

**如下(博主用的貪心水到了80分,也可能是因為資料太弱)

#include

using

namespace std;

int n,x,y,k,tot;

int ans=0;

int sum=0;

int m1,m2;

int mm1,mm2;

int a[10]

[10];

inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}voidin(

)}void

dfs(

int x,

int y,

int s,

int p,

int q)

dfs(x,y+

1,s,p,q)

;dfs

(x+1

,y,s,p,q);if

(s>ans)

}int

main()

} sum+

=tot;tot=0;

while

(mm1>0)

//這裡這裡,鬼畜的求模取數

for(

int i=

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

sum+

=tot;

cout<

return0;

}

ok,今天的這篇就完了。願你不忘初心,歸來仍是少年。︿( ̄︶ ̄)︿

luogu 1006 1004 傳紙條 方格取數

傳紙條 方格取數 這兩道題一樣的 所以我放在一起整理 方格取數比較簡單,記住一條公式,方格任意一點 i j k 2。對於這道題,因為開始從左上角走,所以k是走的步數,所以我們只需要乙個三維dp,f k i j 表示走了k步,第乙個人在第i列,第二個人在第j列,然後根據公式,橫座標也推出來了,所以複雜...

方格取數(dp)

時間限制 1 sec 記憶體限制 128 mb 提交 9 解決 4 提交 狀態 討論版 命題人 quanxing 設有n n的方格圖,我們在其中的某些方格中填入正整數,而其它的方格中則放入數字0。如下圖所示 某人從圖中的左上角a出發,可以向下行走,也可以向右行走,直到到達右下角的b點。在走過的路上,...

方格取數 DP

description 設有n n的方格圖 n 10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示 見樣例 某人從圖的左上角的a 點出發,可以向下行走,也可以向右走,直到到達右下角的b點。在走過的路上,他可以取走方格中的數 取走後的方格中將變為數字0 此人從a點到b 點共...