您的位置:首页 > 其它

51NOD 背包问题v2(动态规划)

2016-10-23 14:30 369 查看
有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。
Input
第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)
第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)
Output
输出可以容纳的最大价值。
Input示例
3 6
2 2 5
3 3 8
1 4 1
Output示例
9


典型的多重背包问题,可是我用的是01背包的做法,记得之前也是这样子做。
这里就是把多重背包拆分成01背包的做法。
我之前是1,1,1,1,1....拆的,然后T了。
所以呢,要对此进行优化一下。
怎么优化呢,我们可以根据二进制来拆分背包。
既拆分成1,2,4,8,....... ,( 1<<(n-1) )
那么Ci怎么变化的,就是每一次拆分Ci- 1<<(i+1),
最后还有对Ci进行讨论,如果不为0,需要再开一个空间存剩下的。
然后01背包,dp[j]=max(dp[j],dp[j-w[i]]+v[i]).


#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define Pi 4.0*atan(1.0)

#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-12;
const int maxn = 50010;
using namespace std;

inline int read(){
int x(0),op(1);
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')op=-1,ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*op;
}
int main()
{
int N,W;
N=read(),W=read();
int c,w,p,k,j,re,tmp;
j=-1,k=0;
int n[maxn],m[maxn];
for(int i=0;i<N;++i){
c=read(),w=read(),p=read();
for(int l=1;l<=p;l<<=1){
n[++j]=c*l;
m[j]=w*l;
p-=l;
k++;
}
if(p!=0){
n[++j]=c*p;
m[j]=w*p;
k++;
}
}
int dp[maxn];
mes(dp,0);
for(int i=0;i<k;++i){
for(j=W;j>=n[i];--j){
dp[j]=max(dp[j],dp[j-n[i]]+m[i]);
}
}
cout<<dp[W]<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: