算法1_DP基礎(chǔ)

動態(tài)規(guī)劃 DP:狀態(tài)和轉(zhuǎn)移。

經(jīng)典例題:最長上升子序列 LIS

狀態(tài):f [ i ] 表示以 i 結(jié)尾的上升子序列中的最長長度衙猪。

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[55],f[55];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++){
        f[i]=1;
        for(int j=1;j<=i-1;j++){
            if(a[j]<a[i])
                f[i]=max(f[i],f[j]+1);
        }
    }
    cout<<f[n]<<endl;
    /*for(int i=1;i<=n;i++)
        cout<<f[i]<<" ";*/
    return 0;
}

大佬說:還可以用二分和線段樹進(jìn)行優(yōu)化(還沒學(xué)到馍乙,后面再補(bǔ)吧)
補(bǔ)充思考:楊輝三角:c [ n ] [ m ] = c [ n - 1 ] [ m ] + c [ n - 1 ] [ m - 1 ] ;

01背包

1、題目:

給 n 個物品垫释,每個物品有體積 vi 以及價(jià)值 wi丝格,取 n 個物品的一個子集,使體積和不超過 m棵譬,并且價(jià)值和盡量

2显蝌、狀態(tài):

f [ i ] [ j ] 考慮前 i 個物品,占用體積為 j订咸,能得到的最大價(jià)值

3曼尊、轉(zhuǎn)移:

f [ i ] [ j ] = max ( f [ i - 1 ] [ j ] , f [ i - 1 ] [ j - v [ i ] ] + w [ i ] ) ;
考慮第 i 個物品取還是不取,仍嗳隆:f [ i - 1 ] [ j - v [ i ] ] + w [ i ] 不嚷嫫病:f [ i - 1 ] [ j ]

4、空間優(yōu)化:
(1)滾動數(shù)組

########## 0 // i - 1
++++++*+++ 1 // i
數(shù)組 f [ i ] [ j ] 的取值只與上一行有關(guān)父叙,開數(shù)組 f [ 2 ] [ maxn ]
用 f [ i % 2 ] [ i ] 代表當(dāng)前行 f [ ( i - 1 ) % 2 ] [ j ]代表上一行

(2)更近一步:

從后向前更新神郊,j 以后的是當(dāng)前行,j 以前的是上一行趾唱。
<><><><>0
######## ++
<><><><>1

for (int i=1:i<=n;i++)
    for (int j=m;j>=v[i];j--) 
        f[j]=max(f[j],f[j-v[i]]+w[i]);

完全背包

1涌乳、題目:

與 01背包 不同,每個物品可以不限制次數(shù)取
稍微修改轉(zhuǎn)移方程即可:

for(int i=1;i<=n;i++)
    for(int j=v[i];j<=m;j++)
        f[j]=max(f[j],f[j-v[i]]+w[i]);
2甜癞、為什么這個算法就可行呢爷怀?

大佬說:首先想想為什么 01背包 中要按照 v 遞減的次序來循環(huán)。讓 v 遞減是為了保證第 i 次循環(huán)中的狀態(tài) F [ i , v ] 带欢,是由狀態(tài) F [ i - 1 , v - Ci ] 遞推而來。換句話說烤惊,這正是為了保證每件物品只選一次乔煞,保證在考慮 “選入第i件物品” 這件策略時(shí)依據(jù)的是一個絕無已經(jīng)選入第 i 件物品的子結(jié)果 F [ i - 1 , v - Ci ]。而現(xiàn)在完全背包的特點(diǎn)恰是每種物品可選無限件柒室,所以在考慮 “加選一件第 i 種物品” 這種策略時(shí)渡贾,卻正需要一個可能已選入第 i 種物品的子結(jié)果 F [ i , v - Ci ] ,所以就可以并且必須采用 v 遞增的順序循環(huán)雄右。這就是這個簡單的程序?yàn)楹纬闪⒌牡览怼?/p>

多重背包

1空骚、題目:

有 N 種物品和一個容量為 V 的背包纺讲。第 i 種物品最多有 Mi 件可用,
每件耗費(fèi)的空間是Ci囤屹,價(jià)值是Wi熬甚。求解將哪些物品裝入背包
可使這些物品的耗費(fèi)的空間總和不超過背包容量,且價(jià)值總和最大肋坚。

2乡括、基本算法:

因?yàn)閷τ诘?i 種物品有 Mi + 1 種策略:取 0 件,取 1 件…取 Mi 件智厌。令 F[i, v]
表示前 i 種物品恰放入一個容量為 v 的背包的最大價(jià)值诲泌,則有狀態(tài)轉(zhuǎn)移方程:
F [ i , v ] = max{ F [ i - 1 , v - k ? Ci ] + k ? Wi | 0 ≤ k ≤ Mi }

3、利用二進(jìn)制轉(zhuǎn)化為 01背包問題

方法:將第 i 種物品分成若干件 01 背包中的物品铣鹏,其中每件物品有一個系數(shù)敷扫。這件物品的費(fèi)用和價(jià)值均是原來的費(fèi)用和價(jià)值乘以這個系數(shù)。令這些系數(shù)分別為1, 2, 2 ^ 2. . . 2 ^ ( k - 1 ), Mi - 2 ^ ( k + 1 )诚卸,且 k 是滿足 Mi - 2 ^ ( k + 1 ) > 0 的最大整數(shù)葵第。
例如:如果 Mi 為 13,則相應(yīng)的 k = 3惨险,這種最多取 13 件的物品應(yīng)被分成系數(shù)分別為 1, 2, 4, 6 的四件物品羹幸。這樣就將第 i 種物品分成了 O ( log Mi ) 種物品

#include<iostream>
using namespace std;
const int N=11010,M=2010;
int n,m;
int V[N],W[N];
int f[M];
int main()
{
    cin>>n>>m;
    int cnt=1;
    for(int i=1;i<=n;i++)  //拆分打包
    {
        int v,w,s;
        cin>>v>>w>>s;
        int k=1;
        while(k<=s)
        {
            V[cnt]=v*k;
            W[cnt]=w*k;
            s-=k;
            k*=2;
            cnt++;
        }
        if(s>0)
        {
            V[cnt]=s*v;
            W[cnt]=s*w;
            cnt++;
        }
    }
    for(int i=1;i<=cnt;i++)
        for(int j=m;j>=V[i];j--)
            f[j]=max(f[j],f[j-V[i]]+W[i]);
    cout<<f[m]<<endl;
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市辫愉,隨后出現(xiàn)的幾起案子栅受,更是在濱河造成了極大的恐慌,老刑警劉巖恭朗,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屏镊,死亡現(xiàn)場離奇詭異,居然都是意外死亡痰腮,警方通過查閱死者的電腦和手機(jī)而芥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膀值,“玉大人棍丐,你說我怎么就攤上這事〔滋ぃ” “怎么了歌逢?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長翘狱。 經(jīng)常有香客問我秘案,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任阱高,我火速辦了婚禮赚导,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赤惊。我一直安慰自己吼旧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布荐捻。 她就那樣靜靜地躺著黍少,像睡著了一般。 火紅的嫁衣襯著肌膚如雪处面。 梳的紋絲不亂的頭發(fā)上厂置,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音魂角,去河邊找鬼昵济。 笑死,一個胖子當(dāng)著我的面吹牛野揪,可吹牛的內(nèi)容都是我干的访忿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼斯稳,長吁一口氣:“原來是場噩夢啊……” “哼海铆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挣惰,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卧斟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后憎茂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體珍语,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年竖幔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了板乙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡拳氢,死狀恐怖募逞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馋评,我是刑警寧澤凡辱,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站栗恩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜磕秤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一乳乌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧市咆,春花似錦汉操、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搜变,卻和暖如春采缚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挠他。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工扳抽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殖侵。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓贸呢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拢军。 傳聞我的和親對象是個殘疾皇子楞陷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355