洛谷P1049 [NOIP2001 普及組] 裝箱問題
阿新 • • 發佈:2022-03-15
本題就是一個簡單的01揹包問題
1.因為每個物品只能選一次,而且要使箱子的剩餘空間為最小。所以可以確定屬性為 MAX
2.由於是從n個物品裡面選i個物品 那麼就是選出的i個物品的空間總和要儘可能的大
就可以得到動態規劃的表示式
f[i][j] = max(f[i-1][j],f[i-1][j-w[i]] + w[i]);
就可以得到完整的程式碼
#include <iostream> using namespace std; const int N = 55 , M = 20010; int f[M][M]; int w[N]; int n; int v; int main() { cin>> v >> n; for ( int i = 1; i <= n; i++ ) cin >> w[i]; for( int i = 1 ; i <= n ; i++ ) for( int j = 0 ; j <= v ; j++ ) { f[i][j] = f[i -1][j]; if( j >= w[i] ) f[i][j] = max(f[i-1][j],f[i-1][j-w[i]] + w[i]); } cout << v - f[n][v];return 0; }
我覺得這個還是不夠好,由於此題是線性Dp所以我們用滾動陣列進行優化
得到以下程式碼,一下就變快了不少呢
#include <iostream> using namespace std; const int N = 55 , M = 20010; int f[M]; int w[N]; int n; int v; int main() { cin >> v >> n; for ( int i = 1; i <= n; i++ ) cin >> w[i]; for ( int i = 1 ; i <= n; i++ )for ( int j = v; j >= w[i]; j-- ) { f[j] = max(f[j],f[j - w[i]] + w[i]); } cout << v - f[v]; return 0; }