2021.02.02
背包问题(dp)
01背包
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int M = 1010;
int dp[M], v[M], w[M];
int main() {
int maxn,p, n, m;
while (cin >> n&&n)
{
maxn = 0;
for (int i = 1; i <= n; i++)
cin >> v[i];
for (int i = 1; i <= n; i++)
{
if (v[i] > maxn)
{
maxn = v[i];
p = i;
}
}
cin >> m;
if (m < 5)
{
cout << m << endl;
continue;
}
memset(dp, 0, sizeof dp);
for (int i = 1; i <= n; i++)//01背包数据仅可使用一次
{
if (i == p)
continue;
for (int j = m-5; j >= v[i]; j--)//01背包 j递减
{
dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
}
}
cout <<m-dp[m-5]-maxn << endl;
}
return 0;
}
完全背包
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int M = 1e5+10;
int dp[M], v[M], w[M];
int main() {
int maxn,p, n, m;
while (scanf("%d",&n)!=EOF)
{
for (int i = 1; i <= n; i++)//数据可多次使用
cin >> v[i]>>w[i];
cin >> m;
memset(dp, 0, sizeof dp);
for (int i = 1; i <= n; i++)
{
for (int j = w[i]; j <=m; j++)//j递增
{
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
}
cout <<dp[m]<<endl;
}
return 0;
}
多重背包
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int M =1000+10;
int dp[M], v[M], w[M];
int num[M],nv[M],nw[M];
int main() {
int t, n, m;
cin >> t;
while (t--)
{
int nn = 0;
cin >> n >> m;
memset(dp, 0, sizeof dp);
for (int i = 1; i <= m; i++)
{
cin >> w[i] >> v[i] >> num[i];//重量 价值 数量
for (int j = 1; j <=num[i]; j*=2)
{
nn++;
nw[nn] = w[i] * j;
nv[nn] = v[i] * j;
num[i] -= j;
}
if (num[i])
{
nn++;
nw[nn] = w[i] * num[i];
nv[nn] = v[i] * num[i];
}
}
for(int i=1;i<=nn;i++)
for (int j = n; j >= nw[i]; j--)
{
dp[j] = max(dp[j], dp[j-nw[i]]+nv[i]);
}
cout <<dp[n]<<endl;
}
return 0;
}