[wikioi]装箱问题
http://wikioi.com/problem/1014/01背包問題是最經典的動態規劃之一,這道題目甚至是這其中還簡單的一種,因為價值就是本身的重量了。本來比如,w是總重量限制,v[]是每個的價值。
但一開始我都有點忘了,查找了一下又勾起了回憶。
1.它把總重量從1到w作為狀態,對初學者并不是很直觀的。但DP本來就是空間換時間的算法,里面經常以整數做狀態,數目還既不是太大又不是太小。最終經常是n^2或n^3的復雜度。
2.01背包問題是個二維數組的DP,狀態轉移方程式f[i,v]=max(f[i-1,m],f[i-1,m-w[i]]+v[i])。其中f[i,m]表示前i個元素在m是重量限制時的價格最大值。f[i-1,m]表示不選擇i的情況,后面是選擇i的情況。
3.但注意到f[i-2,m]肯定小于f[i-1,m]所以可以只保留f[m]作為當前m為重量限制時的價格最大值,那么f[m]=max(f[m-w[i]]+v[i],f[m])。化二維為一維。
4.本人的AC程序仍然用了二維數組,下次可以簡化。
5.要注意邊界條件i<=v,這里最大重量是可以取到的。
可參考:http://www.cnblogs.com/fly1988happy/archive/2011/12/13/2285377.html
#include <iostream>
using namespace std;
int mx[31][20005];
int w[31];
int main()
{
int v;
int n;
cin >> v;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> w[i];
}
for (int i = 0; i <= v; i++)
for (int j = 0; j < n; j++)
{
if (j==0)
{
if (w[j] <= i)
mx[j][i] = w[j];
else
mx[j][i] = 0;
}
else
{
if (w[j] > i)
mx[j][i] = mx[j-1][i];
else
{
int v1 = mx[j-1][i]; // not take w[j]
int v2 = mx[j-1][i-w[j]]+w[j];
mx[j][i] = v1 > v2 ? v1 : v2;
}
}
}
cout << (v - mx[n-1][v]);
}
PPT:http://wenku.baidu.com/view/cf389ab069dc5022aaea00c7.html
對于資源類動態規劃問題,我們可以看出,問題描述必須有一個基本要素:資源,有時這種資源可能是金錢、空間或者時間,問題就是要對這些資源如何分配,一種基本的想法是將資源應用于前i個階段,然后考慮第i個階段和前i-1個階段之間的關系。
設前i個點的消耗j的資源得到的最優值,研究前i-1個點消耗的資源的最優值,利用第i個點決策轉移。
狀態轉移方程一般可寫成: fi(j) = min{ fi-1 ( k) + ui (j,k)}
總結
以上是生活随笔為你收集整理的[wikioi]装箱问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iwatch怎么开机(iwatch绿色闪
- 下一篇: 旅游险多少钱(一般出去旅游多少钱保险)