ZOJ 3725 概率dp
相關推薦
ZOJ 3725 概率dp
太差勁了 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath>
ZOJ 3288 概率dp
題目大意 給定一個\\(n \\times m\\)的棋盤,每天隨機往裡面一個空位置放一個棋子,問期望多少天之後棋盤每一行都有至少一個棋子,每一列至少一個棋子。
ZOJ - 3640 Help Me Escape 概率DP
ZOJ-3640 Help Me Escape 概率DP 題意 有一個人要逃離一個洞穴,現提供 \\(n\\) 條出路,每條出路有危險值 \\(c_i\\) ,這個人的武力值為\\(f\\) 。
codeforces---167BWizards and Huge Prize 概率DP
題目連結:https://codeforces.com/problemset/problem/167/B 題目大意:有n場比賽,你至少要贏l次才算優秀,你有一個大小為k的包,每場比賽的勝率為$p_i$,每場比賽贏得的獎品為$a_i$如果$a_i<0$則是獎品,否則就
codeforces--698C LRU狀壓+概率DP
題目連結:https://codeforces.com/problemset/problem/698/C 題目大意:有n種節目,每個節目出現的概率為$p_i$,電視的快取大小為V,當快取滿了後會擠掉出現次數最少的節目,問在$10^{100}$次詢問後每個節目存在快取
[CF768D] Jon and Orbs - 概率dp
Description \\(n\\) 種物品,求一次取一件把所有種類取遍的概率不小於給定值 \\(p/2000\\) 的最小天數。
【解題報告】【概率DP入門】 P1850 換教室
這道題是一道非常基本的期望的題目,我們只需要抓住關鍵,就是我們遞推直接進行DP就可以了,至於我們的最短路部分,因為資料並不是非常的大,所以說我們直接使用弗洛伊德演算法即可。然後根據期望的定義,我們使用期
HDU多校2020 第七場 E-Expectation(概率DP-算貢獻的期望DP
題意:http://acm.hdu.edu.cn/showproblem.php?pid=6848 有n個小球,n+1個桶還有他們分別在數軸上的位置,交錯排列,每次隨機選一個小球往隨機一個方向滾,遇到洞就掉下去,小球滾進洞後其他球可以在它上面溜過去。
2019徐州網路賽 Random Access Iterator (概率dp)
設計dp狀態為f[i]表示以i為根的子樹能到達正確答案的概率是多少,那麼f[1]就是答案
收集郵票(概率dp)
題目大意 有n種不同的郵票,皮皮想收集所有種類的郵票。唯一的收集方法是到同學凡凡那裡購買,每次只能買一張,並且買到的郵票究竟是n種郵票中的哪一種是等概率的,概率均為1/n。但是由於凡凡也很喜歡郵票,所以皮皮
禮物(概率dp)
題目大意 夏川的生日就要到了。作為夏川形式上的男朋友,季堂打算給夏川買一些生 日禮物。
[POJ 3071]Football[概率DP]
[POJ 3071]Football[概率DP] 題目大意 有 \\(2^n\\) 個編號為 \\(1, 2, 3, \\ldots, 2^n\\) 的隊伍進行足球比賽,一開始 \\(1\\) 和 \\(2\\) 打,\\(3\\) 和 \\(4\\) 打... 贏得隊伍按照原來的相對順序重新編號 \\(1
HDU 4089 Activation(概率dp)
HDU 4089 Activation 連結:https://ac.nowcoder.com/acm/problem/210487 來源:牛客網 題目描述
[SDOI2012]走迷宮 強連通+概率DP+高斯消元
題目 ([SDOI2012]走迷宮) https://ac.nowcoder.com/acm/problem/20575 題目描述 Morenan被困在了一個迷宮裡。迷宮可以視為N個點M條邊的有向圖,其中Morenan處於起點S,迷宮的終點設為T。可惜的是,Morenan非常的腦小
Broken robot CodeForces - 24D (三對角矩陣簡化高斯消元+概率dp)
題意: 有一個N行M列的矩陣,機器人最初位於第i行和第j列。然後,機器人可以在每一步都轉到另一個單元。目的是轉到最底部(第N個)行。機器人可以停留在當前單元格處,向左移動,向右移動或移動到當前位置下方的單元
Atcoder Educational DP Contest I - Coins (概率DP)
題意:有\\(n\\)枚硬幣,每枚硬幣拋完後向上的概率為\\(p[i]\\),現在求拋完後向上的硬幣個數大於向下的概率.
TopCoder - 12349 SRM579 Round1 Div1 RockPaperScissors (概率dp)
TopCoder - 12349 SRM579 Round1 Div1 RockPaperScissors (概率dp) 題目大意: 有\\(n\\)個骰子,每個骰子有300個面,其中有\\(a_i,b_i,c_i\\)分別為石頭/布/剪刀
BZOJ-3450 Tyvj1952 Easy(概率dp)
題目描述 有一個長為 \\(n(n\\leq 3\\times 10^5)\\) 的字串,有的字元是 o,有的字元是 x,有的字元是 ?,表示 o 和 x 各有 \\(50\\%\\) 的可能性,分數是按 \\(comb\\) 計算的,連續 \\(a\\) 個 \\(comb\\) 就
BZOJ-4318 OSU!(概率dp)
題目描述 一共有 \\(n(n\\leq 10^5)\\) 次操作,每次操作只有成功與失敗之分,成功對應 \\(1\\),失敗對應 \\(0\\),\\(n\\) 次操作對應為一個長度為 \\(n\\) 的 \\(01\\) 串。在這個串中連續的 \\(x\\) 個 \\(1
luogu P6835 概率DP 期望
luogu P6835 概率DP 期望 洛谷 P6835 原題連結 題意 n + 1個節點,第i個節點都有指向i + 1的一條單向路,現在給他們新增m條邊,每條邊都從一個節點指向小於等於自己的一個節點,現在從1號點開始走,每次等概率地選擇
百度之後得到結論:
python 中的 and 從左到右計算表示式,若所有值均為真,則返回最後一個值,若存在假,返回第一個假值;
or 也是從左到有計算表示式,返回第一個為真的值;
其中數字 0 是假,其他都是真;
字元 "" 是假,其他都是真;
一開始輸入了
a = 00111100
這麼個賦值語句被提示了錯誤,於是去搜了下相關的部落格得知 python 中數字有以下的表示方式:
2 進位制是以 0b 開頭的: 例如: 0b11 則表示十進位制的 3
8 進位制是以 0o 開頭的: 例如: 0o11 則表示十進位制的 9
16 進位制是以 0x 開頭的: 例如: 0x11 則表示十進位制的 17
但是在測試的時候又遇到了個問題,那就是輸出來的被自動轉化成了十進位制:
>>> a=0b111100 >>> a 60
於是又去找了怎麼輸出二進位制,得到了以下內容:
分別使用 bin,oct,hex 可輸出數字的二進位制,八進位制,十六進位制形式,例如:
>>> a=0b111100 >>> a=60 >>> bin(a) '0b111100' >>> oct(a) '0o74' >>> hex(a) '0x3c'
疑問解決!
剛開始學 python,當想要自增運算的時候很自然的 a++,結果發現編譯器是不認識 ++ 的,於是去網上搜了一下,結果發現一篇老外的問答很精彩,涉及到了 python 這個語言的設計原理。
問題無外乎就是 python 沒有自增運算子,自增操作是如何實現的。
回答中有人介紹了關於自增操作,python 不使用 ++ 的哲學邏輯:編譯解析上的簡潔與語言本身的簡潔,就不具體翻譯了。
後面還有老外回答並附帶了一個例子非常的精彩,指出了 python 與 c 語言概念上的一些差異,語言描述的可能未必準確,直接上例子:
>>> b = 5 >>> a = 5 >>> id(a) 162334512 >>> id(b) 162334512 >>> a is b True
可以看出, python 中,變數是以內容為基準而不是像 c 中以變數名為基準,所以只要你的數字內容是5,不管你起什麼名字,這個變數的 ID 是相同的,同時也就說明了 python 中一個變數可以以多個名稱訪問。
這樣的設計邏輯決定了 python 中數字型別的值是不可變的,因為如果如上例,a 和 b 都是 5,當你改變了 a 時,b 也會跟著變,這當然不是我們希望的。
因此,正確的自增操作應該 a = a + 1 或者 a += 1,當此 a 自增後,通過 id() 觀察可知,id 值變化了,即 a 已經是新值的名稱。
糾正一下樓上的一些觀點
樓上的同學所說的在指令碼式程式設計環境中沒有問題。但是在互動式環境中,編譯器會有一個小整數池的概念,會把(-5,256)間的數預先建立好,而當a和b超過這個範圍的時候,兩個變數就會指向不同的物件了,因此地址也會不一樣,比如下例:
>>> a=1000 >>> b=1000 >>> id(a);id(b) 2236612366224 2236617350384 >>>
位運算,是自己平時最不熟悉的一塊,相信很多人也是這樣,但巧妙的運用位運算可以來解決很多題目,例如,劍指offer上面的一道:
輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。
# -*- coding:utf-8 -*- class Solution: def NumberOf1(self, n): # write code here cnt = 0 if n<0: n = n & 0xffffffff while n: cnt+=1 n = (n-1) & n return cnt
通過按位與,巧妙的計算出二進位制中"1"的個數。
is 和 ==
is 判斷兩個變數是否是引用同一個記憶體地址。
== 判斷兩個變數是否相等。
如果不用 a = b 賦值,int 型時,在數值為 -5~256(64位系統)時,兩個變數引用的是同一個記憶體地址,其他的數值就不是同一個記憶體地址了。
也就是,a b 在 -5~256(64位系統)時:
a = 100 b = 100 a is b # 返回 True
其他型別如列表、元祖、字典讓 a、b 分別賦值一樣的時:
a is b # 返回False
== 和 is 的區別
is 判斷兩個物件是否為同一物件, 是通過 id 來判斷的; 當兩個基本型別資料(或元組)內容相同時, id 會相同, 但並不代表 a 會隨 b 的改變而改變。
== 判斷兩個物件的內容是否相同, 是通過呼叫 __eq__() 來判斷的。
1、當列表,元組,字典中的值都引用 a,b 時,總是返回 True,不受 a,b 值大小的影響
a=1000 b=1000 list1=[a,3,5] list2=[b,4,5] print(list1[0] is list2[0]) tuple1=(a,3,5) tuple2=(b,4,5) print(tuple1[0] is tuple2[0]) dict1={6:a,2:3,3:5} dict2={1:b,2:4,3:7} print(dict1[6] is dict2[1])
輸出結果為:
True True True
2、當不引用a,b,直接用具體值來測試時,列表,字典,不受值大小影響,返回True,元組則受 256 值範圍的影響,超出範圍則地址改變,返回 False。
list1=[1000,3,5] list2=[1000,4,5] print(list1[0] is list2[0]) tuple1=(1000,3,5) tuple2=(1000,4,5) print(tuple1[0] is tuple2[0]) dict1={6:1000,2:3,3:5} dict2={1:1000,2:4,3:7} print(dict1[6] is dict2[1])
輸出結果為:
True False True
3、當直接用列表、元組、字典本身來測試時,剛好相反,元組返回 True,列表,字典返回 False。
list1=[1000,3,5] list2=[1000,3,5] print(list1 is list2) tuple1=(1000,3,5) tuple2=(1000,3,5) print(tuple1 is tuple2) dict1={1:1000,2:3,3:5} dict2={1:1000,2:3,3:5} print(dict1 is dict2)
輸出結果為:
False True False
關於 is 和 == 的標識問題
(1)只要是變數的值相同,標識都相同,沒有-5~256的限制,看下面的例子:
a = 100000 b = 100000 if a is b: print('a 和 b 標識相同,標識為:',id(a)) else: print('a 和 b 標識不相同,a 標識為:',id(a),'b 標識為:',id(b))
輸出結果為:
a 和 b 標識相同,標識為: 2158477874512
(2)同樣的如果是負數,仍然沒有上述限制:
a = -100000 b = -100000 if a is b: print('a 和 b 標識相同,標識為:',id(a)) else: print('a 和 b 標識不相同,a 標識為:',id(a),'b 標識為:',id(b))
輸出結果為:
a 和 b 標識相同,標識為: 2137845175632
(3)列表也是一樣的,只要是列表項數值一樣,那麼標識也是一樣的。例子如下:
list1 = [10000,20000,30000] list2 = [10000,12000,15000] if list1[0] is list2[0]: print('list1[0] 和 list2[0] 標識相同,標識為:',id(list1[0])) else: print('list1[0] 和 list2[0] 標識不相同,list1[0]標識為:',id(list1[0]),'list2[0]標識為:',id(list2[0]))
輸出結果為:
list1[0] 和 list2[0] 標識相同,標識為: 1375086286224
(4)元組的標識是跟著變數名的,變數名不一樣,標識也不一樣,上例子:
tuple1 = (10000,20000,30000) tuple2 = (10000,12000,15000) if tuple1[0] is tuple2[0]: print('tuple1[0] 和 tuple2[0] 標識相同,標識為:',id(tuple1[0])) else: print('tuple1[0] 和 tuple2[0] 標識不相同,tuple1[0] 標識為:',id(tuple1[0]),'tuple2[0]標識為:',id(tuple2[0]))
輸出結果為:
tuple1[0] 和 tuple2[0] 標識不相同,tuple1[0] 標識為: 1375086286384 tuple2[0]標識為: 1375086286480
(5)字典和列表是一樣的,只要是列表項數值一樣,那麼標識也是一樣的。例子如下:
dict1 = {1:10000,2:20000,3:30000} dict2 = {1:10000,2:12000,3:15000} if dict1[1] is tuple2[1]: print('dict1[1] 和 tuple2[1] 標識相同,標識為:',id(dict1[1])) else: print('dict1[1] 和 tuple2[1] 標識不相同,dict1[1] 標識為:',id(dict1[1]),'tuple2[1] 標識為:',id(dict2[1]))
輸出結果為:
dict1[1] 和 tuple2[1] 標識不相同,dict1[1] 標識為: 1375086286224 tuple2[1] 標識為: 1375086286224
深刻理解 and、or 邏輯運算子:
print(0 and 1) # =>0,0等同於False print(False and 1) # =>False print(-1 and 1) # =>1 print(1 or False) # =>1,非零等同於True print(True or False)# =>True print(-1 or 0) # =>-1
優先順序:not>and>or
print(1 and 0 or not False) #=>True print( not False or 1 and 0) #=>True print( 1 or not True and 0) #=>1
看了 "is" 和 "==" 的區別,我有了進一步的瞭解。
is 是比較物件是否相同(is 表示物件識別符號即 object identity),即用 id() 函式檢視的地址是否相同,如果相同則返回 True,如果不同則返回 False。is 不能被過載。
== 是比較兩個物件的值是否相等,此操作符內部呼叫的是 __eq__() 方法。所以 a==b 等效於a.__eq__(b),所以 = 可以被過載。
and or not
優先順序:
() > not > and > or
1.or
在 Python 中,邏輯運算子 or,x or y, 如果 x 為 True 則返回 x,如果 x 為 False 返回 y 值。因為如果 x 為 True 那麼 or 運算就不需要在運算了,因為一個為真則為真,所以返回 x 的值。如果 x 的值為假,那麼 or 運算的結果取決於 y,所以返回 y 的值。
print(1 or 2) # 1 print(3 or 2) # 3 print(0 or 2) # 2 print(0 or 100) # 100 print(0 or 0)
2.and
在 Python 中,邏輯運算子 and,x and y,如果 x 為 True 則返回 y 值。如果 x 為 False 則返回 x 值。如果 x 的值為 True,and 的運算不會結束,會繼續看 y 的值,所以此時真與假取決於 y 的值,所以 x 如果為真,則返回 y 的值。如果 x 為假,那麼 and 運算就會結束運算過程了,因為有一個為假則 and 為假,所以返回 x 的值。
print(1 and 2) # 2 print(3 and 0) # 0 print(0 and 2) # 0 print(3 and 2) # 2 print(0 and 0) # 0
3.混合例子與解析
按照從左向由,優先順序高的先執行優先順序高的規則,首先因為比較運算子優先順序高於邏輯運算子,很簡單,如果運算子低於了邏輯運算子優先順序那還如何運算呢。and 優先順序大於 or,not 優先順序大於 and 和 or。
not 4 > 5 為 True
1 > 2 為 False
3 < 2 為 False
Flase and 3 為 False,因為False為假所以and不在運算直接返回False
4 and False 為 False,因為 4 為真所以 and 運算子會繼續運算後面的,以 False 為主,所以返回 False。
False or False 為 False
False or True 為 True
False or False 為 False,因為 False 為假,所以 or 運算子會繼續運算後面的,以 False 為主,所以返回後面的 False 值
劍指offer上面的一道:
# -*- coding:utf-8 -*- class Solution: # bin函式: bin返回一個整數的二進位制字串,以0b開頭, # bin(10) '0b1010' bin(-10) '-0b1010' # # count函式 返回字串當中非重疊的字串的個數,可以傳入start,end來表示對字串切片的結果 # #如果一個數為負數,那麼2**32 + n 然後再用bin返回的就是它的補碼形式。 補碼+原始碼=2**32 def NumberOf1(self, n): if n >= 0: return bin(n).count('1') else: return bin(2**32 + n).count('1') if __name__ == '__main__': solution = Solution() print(solution.NumberOf1(10)) print(solution.NumberOf1(-10))
除了使用python內建的bin函式和字串計數方法count求二進位制資料的1的個數外,用自己的表示式求解可如下做:
a = 60 #其二進位制值為0b00111100 n = 0 #用於計數 while a: #用移位方法求解,直到a移位為0為止 if a & 1 == 1: n += 1 #將a與1進行位與操作,即可知道a的最後1位是否為1,若為1,則計數n增1,不然則無需變化n的值 a >>= 1 #測試了a的最後一位後,將最後一位右移移除,重新賦值給a print(n) #列印最後的計數資料
以上程式碼顯示n=4,計算正確。