1. 程式人生 > 其它 >洛谷P1049 [NOIP2001 普及組] 裝箱問題

洛谷P1049 [NOIP2001 普及組] 裝箱問題

本題就是一個簡單的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; }