演算法學習 - 動態規劃(DP問題)(C++)

來源:互聯網
上載者:User

標籤:動態規劃   c++   裝配線   

這幾天一直再看,覺得看懂了一些,先記下來。

動態規劃

動態規劃是運籌學的一個方向,就是把多級最佳化問題分解成一系列的單階問題。在不斷增加的過程中,不斷的計算當前問題的最優解。

一般分為如下四個部分:

  • 線性動規:攔截飛彈,合唱隊形,挖地雷,建學校,劍客決鬥等;
  • 地區動規:石子合并, 加分二叉樹,統計單詞個數,炮兵布陣等;
  • 樹形動規:貪吃的九頭龍,二分尋找樹,聚會的歡樂,數字三角形等;
  • 背包問題:01背包問題,完全背包問題,分組背包問題,二維背包,裝箱問題,擠牛奶(同濟ACM第1132題)等;
汽車生產線問題

這個問題是《演算法導論》的動態規劃的例題,我自己覺得這道題比較簡單而且典型,所以就解釋下這個題目:

Colonel汽車公司在有兩條裝配線的工廠裡產生汽車。每一條裝配線上有n個裝配站,
兩條生產線上相同位置的裝配站功能相同,但所需時間不同,並且汽車底盤在兩條
裝配線間轉移要花費一定的時間。如所示兩條生產線。

首先我們知道每個階段的最短時間,都包含了上一階段的最短時間。

而比較簡單的是,我們只有兩種情況,一種是在裝配線1上時間短,一種是在裝配線2上時間短。

假如暴力搜尋,貪心去算得話(也就是遞迴的辦法)。時間複雜就是2^n,這個是不可接受的。

這個時候我們的辦法是先從第一個問題開始,裝配線1, 2上只有一個station。那麼比較簡單,一比較就好了。當有兩個station的時候,就是從上一次比較的結果中(一個line 1最短,一個line 2最短)中繼續加上當前station的值繼續比較。

所以我們發現是每個當前的最優解,都包含了上一次的最優解。

代碼

代碼就是我們從最開始,一直儲存當前問題的最優解,然後去求的下一次的最優解。

////  main.cpp//  DP_line////  Created by Alps on 15/4/26.//  Copyright (c) 2015年 chen. All rights reserved.//#include <iostream>using namespace std;#define NUM 5int main(){    int first[NUM];//到裝備站1,i的最短路徑長度    int second[NUM];//到裝配站2,i的最短路徑長度    int linef[NUM]; //從1進入的路徑    int lines[NUM]; //從2進入的路徑    int a[NUM]; //在裝配站1,i 所需要呆的時間    int b[NUM]; //再裝配站2,i 所需要呆的時間    int m[NUM]; //從裝配站1,i-1 到裝配站2,i的時間    int n[NUM]; //從裝配站2,i-1 到裝配站1,i的時間    int line[NUM]; //當前最短路經所經過的裝配站    int f[NUM]; //當前最短路徑長度    int ea,eb,xa,xb; // ea為進入裝配站1時間,eb為進入2的時間,xa為出裝配站1的時間,xb為出裝配站2的    scanf("%d %d %d %d",&ea,&eb,&xa,&xb);    for(int i=0;i<NUM;++i)    {        scanf("%d %d", &a[i], &b[i]);    }    first[0] = ea + a[0];    second[0] = eb + b[0];    for(int i=0;i<NUM-1;++i)    {        scanf("%d %d", &m[i], &n[i]);    }    for(int i=1;i<NUM;++i)    {        if(first[i-1] + a[i] < second[i-1] + m[i-1] + a[i])        {            first[i] = first[i-1] + a[i];            linef[i] = 1;        }else{            first[i] = second[i-1] + m[i-1] + a[i];            linef[i] = 2;        }        if(second[i-1] + b[i] < first[i-1] + n[i-1] + b[i])        {            second[i] = second[i-1] + b[i];            lines[i] = 2;        }else        {            second[i] = first[i-1] + n[i-1] + b[i-1];            lines[i] = 1;        }    }    for(int i=0;i<NUM;++i)    {        if(first[i] + xa < second[i] + xb)        {            f[i] = first[i] + xa;            line[i] = 1;        }else{            f[i] = second[i] + xb;            line[i] = 2;        }    }    for(int i=0;i<NUM;++i)    {        printf("station %d\n",line[i]);    }    printf("Distince is %d\n",f[NUM-1]);    return 0;}

這個代碼比較簡單,精華就是那個for迴圈了。

測試案例如下:

3 2 3 44 33 66 32 35 22 32 43 44 3

假如有任何建議,歡迎評論。互相學習。謝謝。

演算法學習 - 動態規劃(DP問題)(C++)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.