码迷,mamicode.com
首页 > 其他好文 > 详细

codevs 3269 混合背包

时间:2016-01-08 20:20:43      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

分类讨论~~~~~二进制一定要分出1来。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long f[205005],n,v;
long long w[505],p[505],num[505];
void work1(long long x)
{
for (long long i=w[x];i<=v;i++)
f[i]=max(f[i],f[i-w[x]]+p[x]);
}
void work2(long long x)
{
for (long long i=v;i>=w[x];i--)
f[i]=max(f[i],f[i-w[x]]+p[x]);
}
void work3(long long x,long long numm)
{
long long k=1,w1[255],p1[255],cnt=0;
for (;;)
{
if (k>numm) break;
cnt++;
w1[cnt]=w[x]*k;
p1[cnt]=p[x]*k;
numm=numm-k;
k=k<<1;
}
if (numm>0)
{
cnt++;
w1[cnt]=w[x]*numm;
p1[cnt]=p[x]*numm;
}
for (long long i=1;i<=cnt;i++)
for (long long j=v;j>=w1[i];j--)
f[j]=max(f[j],f[j-w1[i]]+p1[i]);
}
int main()
{
memset(f,0,sizeof(f));
scanf("%lld%lld",&n,&v);
for (long long i=1;i<=n;i++)
scanf("%lld%lld%lld",&w[i],&p[i],&num[i]);
for (long long i=1;i<=n;i++)
{
if (num[i]==-1)
work1(i);
else
work3(i,num[i]);
}
printf("%lld\n",f[v]);
return 0;
}

codevs 3269 混合背包

标签:

原文地址:http://www.cnblogs.com/ziliuziliu/p/5114306.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!