問題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之前,未定義公共模板,待...