兩個問題的對比

2021-07-28 06:46:47 字數 3754 閱讀 1595

問題1(cf390c): 給定若干行聊天記錄 「發言人: 話」, 有些聊天記錄的」發言人」是缺失的, 已知相鄰對話發言人一定不同, 且每個發言人說的話裡都不會包含自己的名字, 現給定可能的發言人的集合, 請填充每個對話的發言人.(來自codeforces round 390:

問題2(lc36): 給定乙個9*9的矩陣, 有些元素為空, 要求使用1-9填充空元素, 使每行, 每列, 每個3*3小矩陣(共9個)中都包含1-9這9個數字.(來自 leetcode:

先說結論, 兩個問題非常相似, 但是第乙個問題可用動態規劃求解; 由於狀態轉移方程極難表述, 第二個問題不能用動態規劃求解

對於lc36, 在初始條件下, 如果我們不對矩陣進行任何填充, 那麼問題的當前狀態可以用一張表進行描述, 注意, 我們可以按照從上到下,從左到右的方式遍歷矩陣的每個元素, 這樣我們用一維序列描述二維矩陣:

元素編號

可能的填充數字1a

11,a12

,...

2a21,..

. ……

81a81,

1,a81

,2,.

..同樣地, 對於cf390c, 在我們填寫發言人之前, 問題的初始狀態也可以用一張表描述:

聊天記錄

可能的發言人

第1條記錄b11

,b12,

...

第2條記錄b21

,...

……第n條記錄bn

1,..

.

一旦我們開始填寫矩陣/發言人, 那麼上述兩張表的狀態就會改變, 而且改變總是會讓每行的」候選集」縮小.即, 我們列出的每行的候選集一定是最終結果的超集.

在lc36的題意下, (i

,j) 表示填第

i 個元素, 使用數字

j, 然後問題跳轉到(i

+1,j

′)在390c的題意下, (i

,j) 表示填第

i 個對話, 使用第

j個人, 然後問題跳轉到(i

+1,j

′)

乍看上去, 這兩個問題是一樣的. 可是我們遺漏了一很關鍵的東西, 就是我們對(i

+1,j

′)的表述是不完整的.因為我們無論何時, 只要我們填寫了

i , 那麼在我們填寫i+

1時就會受到我們剛才的填寫行為的約束. 即問題

i 的決策會對問題i+

1產生影響, 但是我們並沒有表述出這種影響.

對於lc36:(i

,j) 表示第

i 個格仔, 使用j填

問題跳轉到(i

+1) , 引入額外的約束:」不能使用

j 」, 為了表述額外約束, 我們需要修改問題的表示形式

於是我們返回去重新表述(i

): 填寫第

i 個格仔, 使用數字

j, 不能使用的數字列表為

k , 記為(i

,j,k

)問題再次跳轉到(i

+1) : 填寫第i+

1 個格仔, 使用數字j′

, 不能使用的數字列表為k,

j , 記為(i

+1,j

′,[k

,j′]

)

這樣可以構造dp問題[y

,x,i

,m] 表示在不能使用數字的遮蔽碼為m的情況下用

i 臺填寫格仔(y

,x),並且不會破壞矩陣性質的可能性(可能/不可能), 複雜度是: 9*9*9*512 < 1000 * 600 = 600, 000, 貌似可解

而對於390c:(i

,j) 表示, 填寫第

i 行, 使用人物

j然後跳轉到(i

+1) , 問題表述為填寫第i+

1 行, 使用人物j′

, 不能使用人物

j , 引入新的約束, 需重新表示問題

重新表述

i為, 填寫第

i 行, 使用人物

j, 不能使用人物

k , 記為(i

,j,k

)再次跳轉到i+

1 , 問題表述為填寫

i 個格仔, 使用人物j′

, 不能使用人物

j , 記為(i

+1,j

′,j)

至此, 可以構造dp問題[i

,j,k

] , 表示從第

i 個人開始填寫, 使用

j號人物, 不能使用

k 號人物, 最終可以成功填寫的可能性(可能/不可能).

這兩個問題再以下方面是相同的:

都是乙個乙個的填寫, 並且每個都有個候選列表

填寫乙個以後, 會影響其他人的填寫

但是cf390c和lc36相比有個關鍵的不同點:前者跳轉時, 會不攜帶來自(i

−1)的約束, 而後者會攜帶來自(i

−1) 的約束:

對於cf390c, 問題的跳轉方式是(i

,j,k

)⟶(i

+1,j

′,j)

, (i

+1) 的第三個狀態與

i 的第三個狀態無關.

對於lc36, 問題的跳轉方式是(i

,j,[

k])⟶

(i+1

,j′,

[k,j

]), (

i+1)

的第三個狀態與

i 的第三個狀態有關.

至此, 我們發現第乙個是普通的動態規劃, 第二個似乎是狀態壓縮動態規劃.可是真是這樣嗎?

對於cf390c, 我們在計算(i

,j,k

)時可以很方便地算出(i

+1) 的兩個狀態引數:

然而, 對於lc36, 我們在計算(i

,j,k

) 時卻很難算出(i

+1) 的第三個引數!我們來看第三個引數的意義:不能使用的數字集合.這個引數的計算過程是這樣的: 一方面, 如果

i 號元素是定值, 那麼第三個引數

k也是定值, 直接計算;另一方面, 如果

i 號元素為空, 那麼第三個狀態

k的計算要考慮如下因素:

元素在矩陣中受到的天然限制: 行, 列, 小3*3小矩陣中的元素.這個限制就是第1節中的表的限制.

元素受到

i 的限制: 父元素

i有自己的不可用數字集合, 這個集合中的數字來自于父元素

i 的表, 以及父元素

i的父元素(i

−1) .

這樣一來, 如果你要計算(i

+1) 的第三個引數, 必須清楚地知道, 父元素不可用數字集中每個數字是如何生成的:

對於受到原始限制的數字, 我們可以通過

i 和i+

1的想對位置, 進行修正. 比如, 若

i 和(i

+1)在同一行,且在同乙個小矩陣中 那麼我們從

i 的原始限制集中去掉通過列限制提供的數字.

對於受到

i的先前元素限制的數字, 我們必須找到他們的生成位置, 然後根據生成位置和(i

+1) 的想對位置, 來計算(i

+1) 的不可用數字集合.

稍加思考就會知道, 上述兩個步驟, 每一步都是幾乎不可實現的.因此, lc36雖然和cf390c非常像, 但是後者可以用dp求解, 但是前者很難用dp求解.

兩個JSON對比

需求 兩個json對比 目前有兩個json 型別的資料,和 對比出來的結構需要有,2 3 4 5 class bo public bo string rowno,string name public string getrowno public void setrowno string rowno ...

兩個檔案對比 C

public static bool filecompare string file1,string file2 int file1byte 0 int file2byte 0 using filestream fs1 new filestream file1,filemode.open fs2 n...

對比兩個公司的CMMI實施

我參與了兩個公司的cmmi實施過程,兩個不同的實施方法,各有利弊。下面將幾個不同做法整理如下 1.模板的作用 公司1在實施cmmi之前,制定了公共文件模板,然後在開發過程文件時,先開發乙個pa,待該pa的所有文件全部評審通過,再以該檔案為樣本開發其他pa。公司2在實施cmmi之前,未定義公共模板,待...