背包类DP
1.01背包:
#include<iostream>
using namespace std;
int n,m,v,w,f[1200];
int main()
{
cin >> n >> m;
do //不能写成while,假如只有一个物品会出问题
{
cin >> v >> w;
for(int j = m;j >= v;--j)
{
f[j] = max(f[j],f[j - v] + w);
}
}while(--n);
cout << f[m] << endl;
return 0;
}
2.完全背包:
#include<iostream>
using namespace std;
int f[1200],w,v;
int main()
{
int n,m;
cin >> n >> m;
do
{
cin >> v >> w;
for(int j = v;j <= m;++j)
{
f[j] = max(f[j],f[j - v] + w);
}
}while(--n);
cout << f[m] << endl;
return 0;
}
3.多重背包:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cstring>
#include<vector>
using namespace std;
int n,m;
int f[2100];
struct node
{
int w1;
int v1;
}t;
vector<node> a;
int main()
{
cin >> n >> m;
for(int i = 1,v,w,s;i <= n;++i)
{
cin >> v >> w >> s;
for(int k = 1;k <= s;k <<= 1)
{
s -= k;
a.push_back((node){k * w,k * v});
}
if(s > 0) a.push_back((node){s * w,s * v});
}
for(vector<node>::iterator it = a.begin();it != a.end();it++)
{
t = *it;
for(int j = m;j >= t.v1;--j)
{
f[j] = max(f[j],f[j - t.v1] + t.w1);
}
}
cout << f[m] << endl;
return 0;
}
4.求方案数类型(这类题大多数为完全背包问题的变形)
练习例题:
1.https://www.acwing.com/problem/content/1373/
2.http://www.rqnoj.cn/problem/98
3.https://www.luogu.com.cn/problem/P2563
4.https://www.luogu.com.cn/problem/P1164
5.https://www.luogu.com.cn/problem/P1832
6…