poj 2184 01背包變形:體積為負數的處理

來源:互聯網
上載者:User

今天遇到一題poj2184,大概思路是01背包dp之後把符合要求的最優解統計出來。但是在解01背包的時候遇到一個問題是體積有負數,這樣在dp的過程中會遇到兩個問題:迴圈的時候超出體積的範圍;壓縮空間的時候狀態轉移方程:dp[v]=max(dp[v],dp[v-c[i]]+w[i]),c[i]為負數時v-c[i]>v,這樣按一般的迴圈的方向從大到下會重複計算。

先看第二個問題,在一般的01背包壓縮空間的時候,體積的遍曆是從大到小,因為dp[v]=max(dp[v],dp[v-c[i]]+w[i]),當前的dp[v]只取決於比自己小的dp[v-c[i]],所以從大到小遍曆時每次dp[v-c[i]]和dp[v]都是上一次的狀態。

如果體積為負v-c[i]>v,從大到小遍曆dp[v-c[i]]是當前物品的狀態,不是上一個,這樣就會出錯,解決的辦法是從小到大遍曆。

針對第一個問題,在處理的時候將整個數軸平移,使得原來所有可能的情況都為正。

例如這題,首先計算出資料的範圍:

一共100組數,從-1000到1000,那麼體積的範圍就是-100*1000到100*1000。平移之後我們要處理的資料範圍就在0到200000,新的原點變成100000。

初始化變成:

        for(int i=0;i<=200000;i++)     dp[i]=-INF;        dp[100000]=0;

迴圈變成:

        for(int i=1;i<=n;i++)        {            if(s[i]>0)            {                for(int v=200000;v>=s[i];v--)//從可能的最大值到最小值                {                   if (dp[v-s[i]]>-INF)                        dp[v]=max(dp[v],dp[v-s[i]]+f[i]);                }            }            else            {                for(int v=0;v-s[i]<=200000;v++)                {                    if (dp[v-s[i]]>-INF)                        dp[v]=max(dp[v],dp[v-s[i]]+f[i]);                }            }        }

計算結果要從100000開始遍曆,因為100000相當於原來的0

        int nMax=0;        for(int v=100000;v<=200000;v++)            if(dp[v]>=0)                nMax=max(nMax,dp[v]+v-100000);

這題還有一種解決方案:把物品的體積全部加1000,使它們都大於0,然後dp的時候用一個數組記錄dp[i][v]時多加了幾個1000,最後在結果裡減去就行了。這個做法有個需要注意的地方是狀態轉移變成:

        for(int i=1;i<=n;i++)            for(int v=sum;v>=s[i];v--)//tot記錄多加的1000                if(dp[v]-tot[v]*1000 <                   dp[v-s[i]]+f[i]-(1+tot[v-s[i]])*1000)                {                    dp[v]=dp[v-s[i]]+f[i];                    tot[v]=tot[v-s[i]]+1;                }

而不是

                if(dp[v]<dp[v-s[i]]+f[i])                {                    dp[v]=dp[v-s[i]]+f[i];                    tot[v]=tot[v-s[i]]+1;                }

因為這時的最大值是某個v+dp[v]-tot[v]*1000,v一定的情況下dp[v]-tot[v]*1000表示的才是最大值,雖然這個最大值的意義不好理解。。

這題的第二種解法只是看結題報告粗淺的理解下,動態規劃真是非常神奇。。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.