[codevs3269]混合背包

题目大意:一道混合背包模板。

解题思路:分三种情况讨论,01和完全没什么问题,多重背包需要把物品分成$log W[i]$件,然后01即可,分成W[i]件01会TLE。

读优大法好!

C++ Code:

#include<cstdio>
#include<cctype>
using namespace std;
#define max(i,j)(((i)>(j))?(i):(j))
char buf[4000004];
int bufpos;
inline void init(){
    bufpos=0;
    buf[fread(buf,1,4000000,stdin)]='';
}
inline int readint(){
    int p=0,flag=false;
    for(;!isdigit(buf[bufpos]);bufpos++)flag=(buf[bufpos]=='-');
    for(;isdigit(buf[bufpos]);bufpos++)
    p=(p<<3)+(p<<1)+buf[bufpos]-'0';
    return (flag)?(-p):(p);
}
int n,v,f[200002];
int main(){
	init();
	n=readint(),v=readint();
	while(n--){
		int V=readint(),W=readint(),M=readint();
		if(M==1)
		for(int i=v;i>=V;--i)
		f[i]=max(f[i],f[i-V]+W);
		else
		if(M==-1)
		for(int i=V;i<=v;++i)
		f[i]=max(f[i],f[i-V]+W);
		else{
			int k=1,p=1;
			while(p<=M){
				for(int i=v;i>=V*k;--i)
				f[i]=max(f[i],f[i-V*k]+W*k);
				p+=(k*=2);
			}
			p=M-p+k;
			for(int i=v;i>=V*p;--i)
			f[i]=max(f[i],f[i-V*p]+W*p);
		}
	}
	printf("%d
",f[v]);
	return 0;
}
原文地址:https://www.cnblogs.com/Mrsrz/p/7281721.html