【0-1 背包模板】 poj 3624

时间:2023-03-10 04:36:00
【0-1 背包模板】 poj 3624

先看个未经优化的二维空间dp:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <memory.h>
using namespace std;
const int maxn1=;
const int maxn2=;
int dp[maxn2][maxn2];
//int dp[maxn2];
int w[maxn1],v[maxn2];
int m,n;
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++)
cin >> w[i] >> v[i];
}
memset(dp,,sizeof(dp));
int j;
for(int i=;i<=n;i++)
{
for(j=;j<=m;j++)
{
if(j>=w[i])
dp[i][j]=max(dp[i-][j],dp[i-][j-w[i]]+v[i]);
else
dp[i][j] = dp[i-][j];
}
}
cout << dp[n][m] << endl;
return ;
}

改进:

1。二维优化到一维

2。倒写

#include <iostream>
#include <cstdio>
#include <cmath>
#include <memory.h>
using namespace std;
const int maxn1=;
const int maxn2=;
int dp[maxn2],w[maxn1],v[maxn2];
int m,n;
int max(int a, int b)
{
if(a>b) return a ;
else return b ;
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m))
{
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)
cin >> w[i] >> v[i];
int j;
for(int i=;i<=n;i++)
{
for(j=m;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout << j << " j "<< dp[j]<< endl;
}
cout <<endl;
}
cout << dp[m] << endl;
}
return ;
}

给一组数据便于理解:

6 j 4
5 j 4
4 j 4
3 j 4
2 j 4
1 j 4

6 j 10
5 j 10
4 j 10
3 j 10
2 j 6

6 j 22
5 j 18
4 j 16
3 j 12

6 j 23
5 j 19
4 j 16
3 j 12
2 j 7

23

最后给出模板:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <memory.h>
using namespace std; const int maxn1=;
const int maxn2=;
int dp[maxn2],w[maxn1],v[maxn1];
int m,n; int max(int a, int b)
{
if(a>b) return a ;
else return b ;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)
cin >> w[i] >> v[i];
int j;
for(int i=;i<=n;i++)
for(j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout << dp[m] << endl;
}
return ;
}