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;
}
posted @ 2021-05-01 21:55  IdiotNe  阅读(43)  评论(0编辑  收藏  举报