The Robbery
来源:互联网 发布:新款java小轮车 编辑:程序博客网 时间:2024/05/21 22:21
In the downtown of Bucharest there is a very big bank with a very big vault. Inside the vault there are N very big boxes numbered from 1 to N. Inside the box with number k there are k very big diamonds, each of weight Wk and cost Ck.
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
The first line contains single integer T – the number of test cases. Each test case starts with a line containing two integers N and M separated by a single space. The next line contains N integers Wk separated by single spaces. The following line contains N integers Ck separated by single spaces.
Output
For each test case print a single line containing the maximal possible total cost of diamonds.
Sample Input
2
2 4
3 2
5 3
3 100
4 7 1
5 9 2
Sample Output
6
29
Hint
Constraints:
1 ≤ T ≤ 74,1 ≤ N ≤ 15,
1 ≤ M ≤ 1000000000 (109),
1 ≤ Wk, Ck ≤ 1000000000 (109).
Source
Southeastern European Regional Programming Contest 2009
题目分析:
我和很多人一样,第一感觉这是一个多重背包的问题,结果不断爆内存和超时,
后来看了数据范围,才发现,应该用dfs来做,直接暴力裸搜显卡会超时,优化
和剪枝是必须的,下面介绍三个优化与剪枝:
1、将所有砖石按性价比从大到小排列
2、在搜索过程中,假设将还剩有的容量left全部全部装当前砖石,则可获得可能
不存在的最大价值,如果这个价值小于ans,则可以退出该层搜索了
3、同样是在搜索过程中,假设将还剩有箱子的砖石的价值全部加上,如果这个价值
小于ans,则也可以退出该层搜索了
# include<stdio.h># include<string.h>long long w[16],v[16],k[16];int n,m,time;long long ans,sum[16];void swap(long long &x,long long &y){ long long temp; temp=x; x=y; y=temp;}void sort() // 优化一:按性价比从大到小排列{ long long i,j,temp; for (i=1;i<n;i++) for (j=i+1;j<=n;j++) if (v[i]*w[j]<v[j]*w[i]) { swap(w[i],w[j]); swap(v[i],v[j]); swap(k[i],k[j]); }}void put(long long x){ if (ans<x) ans=x;}void dfs(int left,int x,long long value){ int i; if (x>n) { put(value); return; } if (time==30000000) return; double cost; cost=value+((double)left)/w[x]*v[x]; if (cost<ans) return; //优化二 cost=value+sum[n]-sum[x-1]; if (cost<ans) return; //优化三 for (i=k[x];i>=0;i--) if (left>=i*w[x]) { time++; dfs(left-i*w[x],x+1,value+i*v[x]); }}int main(){ int i,t; long long weight; scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); weight=0; for (i=1;i<=n;i++) { scanf("%lld",&w[i]); weight+=w[i]*i; } for (i=1;i<=n;i++) { scanf("%lld",&v[i]); k[i]=i; } sort(); sum[0]=0; for (i=1;i<=n;i++) { sum[i]=sum[i-1]+v[i]*k[i]; } ans=0; int mm=m; for (i=1;i<=n;i++) if (mm>=w[i]) { if (mm>=w[i]*k[i]) { ans+=v[i]*k[i]; mm-=w[i]*k[i]; } else { ans+=(mm/w[i])*v[i]; mm=mm-w[i]*(mm/w[i]); } } //首先构造一个可行的价值 time=0; if (weight>m) dfs(m,1,0); else ans=sum[n]; //如果能全部装下,肯定直接输出所有价值之和啊 printf("%lld\n",ans); }}
- The Robbery
- POJ 3900 The Robbery
- poj 3900 The Robbery (dfs+剪枝)
- POJ 3900 The Robbery (dfs暴搜+剪枝)
- POJ 3900 The Robbery(dfs)
- POJ 3900 The Robbery 已被翻译
- POJ 3900 The Robbery(DFS+剪枝)
- poj 3900 The Robbery(dfs+剪枝,不是背包)
- zoj 1144 Robbery
- poj 1104 Robbery
- [ZOJ1144][POJ1104] Robbery
- zoj 3511 Cake Robbery
- zoj 3511 Cake Robbery
- zoj 3511 Cake Robbery
- ZOJ3511 Cake Robbery,暴力
- poj3900The Robbery(贪心+dfs)
- 搜索 HOJ 1136 Robbery
- UVA 707 - Robbery
- poj-3898 Software Industry Revolution DP
- VS2005升级VS2010遇到的问题解决
- 高斯滤波与SIFT特征检测
- 面试题4:从尾到头打印链表
- 生产者消费者问题(java模拟)
- The Robbery
- MFC ListCtrl控件
- 关于c++的虚函数的一些总结
- 业务逻辑层的设计(三)——事务的考虑
- Qt右击菜单建立
- SQL2008错误
- 关于递归
- poj2112 二分+最大流
- JAVA 游戏开发之——FPS(帧频刷新率)精准控制