易水人去,明月如霜。
Description
John and Brus are inside the vault at the moment. They would like to steal everything, but unfortunately they are able to carry diamonds with the total weight not exceeding M.
Your task is to help John and Brus to choose diamonds with the total weight less than or
equal to M and the maximal possible total cost.
Input
Output
Sample Input
2
2 4
3 2
5 3
3 100
4 7 1
5 9 2
Sample Output
6
29
很容易想成揹包其實是貪心加搜索
代碼:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
char ch;int s=0,f=1;
ch=getchar();
while(ch>'9'||ch<'0'){ if(ch=='-') f*=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-48; ch=getchar(); }
return s*f;
}
struct node {
int w,v,num;
}box[25];
int sum[25];
bool cmp(const node &a,const node &b)
{
return a.v*b.w>b.v*a.w;
}
int n,m;
long long ans;
bool cut(int pos,long long va,int left)
{
if(pos==n+1) return true;
if(va+sum[pos]<=ans) return true;
double best=(box[pos].v*1.0/box[pos].w);
if(va+(long long) (best*left+0.5)<=ans) return true;
return false;
}
void dfs(int pos,long long va,int left)
{
ans=max(ans,va);
if(cut(pos,va,left)) return ;
for(int i=box[pos].num;i>=0;i--)
{
if((left-box[pos].w*i)<0) continue;
dfs(pos+1,va+box[pos].v*i,left-box[pos].w*i);
}
}
int main()
{
int cas;
cas=read();
while(cas--)
{
n=read(),m=read();
ans=0;
long long sumw=0;
long long sumv=0;
for(int i=1;i<=n;i++)
{
box[i].w=read();
sumw+=box[i].w*i;
}
for(int i=1;i<=n;i++)
{
box[i].v=read();
sumv+=box[i].v*i;
box[i].num=i;
}
if(sumw<=m)
{
printf("%lld\n",sumv);
continue;
}
sum[n+1]=0;
sort(box+1,box+1+n,cmp);
for(int i=n;i>=1;i--)
{
sum[i]=sum[i+1]+box[i].v*box[i].num;
}
dfs(1,0,m);
printf("%lld\n",ans);
}
return 0;
}