題意:標準的0-1背包問題。記憶體方面使用滾動數組。時間方面可以先對W[]進行非升排序。本來在輸入資料時候還打算記錄最小重量,在knap時候進行最佳化,但發現結果沒有什麼變數,所以並沒有加上。
C++源碼:
#include <iostream><br />using namespace std;</p><p>const int N = 3402;<br />const int M = 12881;</p><p>short w[N], v[N];<br />int t[M];<br />int n, c;</p><p>void swap(int i, int j){<br /> int tmp = w[i];<br /> w[i] = w[j];<br /> w[j] = tmp;<br /> tmp = v[i];<br /> v[i] = v[j];<br /> v[j] = tmp;<br />}<br />void quickSort(int lo, int hi){<br /> if(lo>=hi) return;<br /> int pivot = w[hi];<br /> int i=lo-1;<br /> int j=hi;<br /> while(i<j){<br /> while(w[++i]>pivot);<br /> while(j>=0 && w[--j]<pivot);<br /> if(i<j) swap(i,j);<br /> }<br /> swap(i,hi);<br /> quickSort(lo,i-1);<br /> quickSort(i+1,hi);<br />}<br />void readin(){<br /> cin >> n >> c;<br /> for(int i=0;i<n;i++)<br /> cin >> w[i] >> v[i];<br />}<br />void knap(){<br /> quickSort(0,n-1);<br /> int little = w[n-1] > c ? c : w[n-1];<br /> for(int i=0;i<little;i++)<br /> t[i] = 0;<br /> for(int i=little;i<=c;i++)<br /> t[i] = v[n-1];</p><p> for(int i=n-2;i>=0;i--){<br /> for(int j=c;j>=0;j--){<br /> if(w[i]<=j)<br /> t[j]=max(t[j],t[j-w[i]]+v[i]);<br /> else<br /> break;<br /> }<br /> }<br />}</p><p>int main(){<br /> readin();<br /> knap();<br /> cout << t[c] << endl;<br /> return 0;<br />}<br />
運行:
C++編譯
memory: 248K
time: 344MS
code: 1140B
總結:
1、最近做的題雖然很基礎,不過想把簡單的問題徹底弄懂。而且比較關注記憶體和時間方面的最佳化,畢竟AC不是目的,目的是能夠學到更多的東西。Status上好多人的演算法都是50MS以內,以後多思考一些最佳化方法。
2、quickSort雖然寫了好多次,但是還是手生,經常搞錯一點,要加強基礎演算法學習。