POJ 1276
多重背包问题的模板题,感觉能学到背包问题这一系列这么精妙的算法实在很幸运。推荐学习背包问题的教程就是崔添翼大牛的背包九讲,之前看过,实践做题第一次,挺开心的。模板就参考kuangbin大牛的,此外,其实崔老师的伪代码看着基本上也能差不多写出来
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;
const int maxv= 1e5+5;
const int maxk= 12;
int n_v, n_k;
int amt[maxk], co[maxk];
int f[maxv];
void ZeroOnePack(int c, int w)
{
for (int v= n_v; v>= c; --v){
f[v]= max(f[v], f[v-c]+w);
}
}
void CompletePack(int c, int w)
{
for (int v= c; v<= n_v; ++v){
f[v]= max(f[v], f[v-c]+w);
}
}
void MultiplePack(int c, int w, int num)
{
if (c*num>= n_v){
CompletePack(c, w);
}
else{
int k= 1;
while (num> k){
num-= k;
ZeroOnePack(k*c, k*w);
k<<= 1;
}
ZeroOnePack(num*c, num*w);
}
}
int main(int argc, char const *argv[])
{
while (~scanf("%d %d", &n_v, &n_k)){
for (int i= 0; i< n_k; ++i){
scanf("%d %d", amt+i, co+i);
}
for (int i= 0; i<= n_v; ++i){
f[i]= 0;
}
for (int i= 0; i< n_k; ++i){
MultiplePack(co[i], co[i], amt[i]);
}
printf("%d\n", f[n_v]);
}
return 0;
}