tot是一定的,
如果某個值x能夠到達,那麼tot-x一定能到達
只用從i=tot/2 逐漸減小 開始檢查 是否i和tot-i都能到達
動態規劃過程中,只用求出0到tot/2是否能達到即可。
hdu 2955 robberies :
01揹包,被抓住的概率應該是一連串概率的乘積,因為把概率當作揹包體積不好計算,而且浮點數本身就有精度問題,
這個題目得把得到的錢數當作揹包的體積,生還的概率當作價值。
poj 2184cow exhibition
01揹包,對一頭牛的兩個值a、b,乙個看成花費,乙個看成是價值。
這也是陣列的運用dp,乙個陣列其實就是乙個對映。在x->dp[x]中,不僅要注意dp[x]的意義,還要充分利用x的意義。
dp[x]表示a值總和為x時,b值和的最大值。
如果花費大於0(一般的01揹包),要逆序遍歷。
如果花費小於0, 則要公升序。
雖然總體積有負數值,我們可以按一定的規則把它存到對應的正值下標x的dp[x]下。
hdu 2639 bone collector ii
要求出第k大的價值,經典的揹包拓展成二維,dp[v][t]表示容量為v的揹包能裝的第t大的價值。
狀態轉移類似於乙個歸併排序。
揹包問題的dp其實有兩種意義,對應不同的轉移。
dp[x]既可以表示容量為x的揹包對應的最大價值,
(此時初始化均為0)
又可以表示裝載了x體積對應的最大價值。
(此時dp[0]初始化為0。其餘可以為負值了 ,表示達不到。)
poj 2923 relocation
除了狀態壓縮,感覺這題是真正的dp基礎題(我是說dp的思路簡單)。但是道好題,整體是有難度的。
hdu 3466 proud merchants
順序性,排序相關。考慮好順序則簡單。細想還是挺難的。
排序要求:need2-cost2>=need1-cost1(2物品後考慮,1物品先考慮,分階段動態規劃,1物品在前)
關鍵是按順序,本次轉移利用的狀態要是先前計算好了的。
對於排序的考慮,只要考慮任意兩個物品之間怎麼排即可。
hdu 2126 buy the souvenirs 01揹包+計數dp
01揹包+計數dp
價值為0時,方法種數為1
hdu 4281 judges' response
集合dp+tsp
集合x是s的子集: s==x|s , x==x&s
集合x與s的有交集: x&s
對於集合s,求它的所有非空真子集: for(int x=(s-1)&s ; x ;x=(x-1)&s )
很方便修改為子集。
01揹包:每個物品只能用一次,
dp[v][i]=min( dp[v-cost][i-1]+val[i],dp[v][i])
其核心思想實質是: 分階段動歸,考慮了第i種物品的結果= 現在試加入第i物品乙個,然後將其與 前i-1個物品的結果
綜合考慮。
不論轉移方程具體如何,其本質如此。
當前利用的結果一定是之前計算好的。對此要設計好順序性及排序方法。
dp[v]
=min( dp[v-cost]+val[i],dp[v])
uva 674 coin change 完全揹包
雖然網上說這是基礎題,感覺其實並不簡單,雖然有人將此題歸為完全揹包,但感覺和經典的揹包轉移還是有些差別。
dp[x][i]表示體積為x時的,前i種物品,能達到的方法種數。
狀態轉移方程:
dp[x][i] =dp[x][i-1]+dp[x-cost[i]][i];
意味對於體積為x的揹包,若考慮將狀態從只用了前
則要將原來的狀態 加上 用了第i種物品時種類數。(其實在x-cost[i]時就已經證明用了第i種物品了)
可用一維陣列表示。
**uva 147 - dollars 完全揹包
可以將5c當作1處理,節約陣列空間。因為貨比都是5的倍數
對於計數dp,一定要想到long long和取模。
**poj 3181 大數/高精度的完全揹包
大數的錢幣兌換問題
**zoj 3623 動態規劃的無後效性 + 問題轉化
zoj 3524 拓撲排序+揹包
zoj 3662 分階段動歸
poj 3260 the fewest coins
混合揹包(完全+多重)+上限處理
poj 2063 investment 貪心+完全揹包
貪心:只要每年的選擇獲利最大即可。
poj 1276 裸多重揹包
hdu 1509 多重揹包,超水
poj 2392 排序(貪心)+dp(揹包)
總結一下,多重揹包就是分解成多個0、1揹包。完全揹包和多重揹包考得似乎比01揹包多。
dp[v]的意義:有些題目是指體積v的揹包能創造最大價值,(不必裝滿)
有的題目是指完全裝滿體積v,能得到的最大價值。
像錢幣兌換問題,dp[v]時價值一定是v,此時可以用bool型表示dp[v]能否達到。
像錢幣兌換的計數dp,dp[v]+=dp[v-cost],dp[v]表示目前湊成v價值的方法數。
使用動態規劃,先要看問題的規模,
然後在關鍵有幾個:1.是找到適當的狀態能表示起點和終點。
2.是狀態轉移方程必須滿足無後效性。(通常符合了這一點應該就可以寫出狀態轉移方程)
3.最優子結構,只有滿足才能用dp
4. 按合理的順序進行動態規劃
其中第三點是使用dp的基礎,難點在於1、2、4三點,如果考察到2,感覺2最難,2和4的聯絡很緊密。
個人感覺,揹包模型很有用,用的時候要找到物品的「花費」和「價值」,才能對應到題目上去。
關於順序性的設計與列舉有密切聯絡,列舉的層次變換了,往往代表不同的意義。
一般來說「消耗」較少,「價值」可能會較大,因為儲存空間有限啊!
對於 dp[v],舉個極端的情形: v就代表數量,我要從100個人中找到10個人,dp[10]代表10個人能到達的某種效果,
這裡的dp[v]是指實際到達了v,而不是花費<=v。乙個人的cost自然是1,
給出乙個for迴圈 for(int v=0;v<=v;v++)
其實這樣就成了分階段的動歸了。
揹包的實質是分階段動歸,然而通常01揹包和完全揹包被省略了一維。
1.對於一般的揹包問題,dp[x]往往單調遞增,有時可以利用這個轉化問題。
動態規劃習題
401最大連續乘積子串 402字串編輯距離 403格仔取數問題 404交替字串 1.子串行個數 子串行的定義 對於乙個序列a a 1 a 2 a n 則非空序列a a p1 a p2 a pm 為a的乙個子串行 其中1 p1 2.數塔取數問題 乙個高度為n的由正整數組成的三角形,從上走到下,求經過的...
動態規劃習題
解題思路 lis lcs 拿數問題 ii 解題思路 東東在玩遊戲 game23 在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出 1。input 輸入的唯一一行包括兩個整數n和m 1 n m ...
動態規劃習題整理(1)
狀態表示 f i 表示以第 i 個元素結尾的所有連續子陣列的最大值。狀態轉移 f i max f i 1 0 nums i f i 可劃分為兩部分,以第 i 1個元素結尾的所有連續子陣列加上第i個元素,或者只選用第 i 個元素。答案為所有f i 中的最大值。優化 由於f i 在計算時只會用到f i ...