poj 3900 dfs搜索剪枝+后缀和预处理+贪心
2018-02-21 15:24
337 查看
点击打开链接
//dfs搜索剪枝+后缀和预处理
//首先利用性价比贪心,单位质量的价值越高则性价比越高
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
int n;
LL m,ans; //m为总重量,ans为最优解
LL sum[200];
struct maze{
LL weight,value;
double pos;
int num; //钻石数量
};
maze field[200];
bool cmp(maze a,maze b)
{
return a.pos>b.pos;
}
void dfs(int x,LL now_value,LL now_weight)
{
ans=max(ans,now_value); //更新最优解
if(now_weight<=0||x>n) return;
if(now_value+sum[x]<=ans) return; //如果当前的价值加上其余钻石的所有价值<=ans,则剪枝
double best=field[x].pos;
if(now_value+(LL)ceil(now_weight*best)<=ans) return; //剩下的重量全部装性价比最高的钻石,如果得到的价值小于此时已经得到的价值,则剪枝
for(int i=field[x].num;i>=0;i--) //先选择性价比较高的箱子
{
if(now_weight<field[x].weight*i) continue;
dfs(x+1,now_value+field[x].value*i,now_weight-field[x].weight*i);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d%lld",&n,&m);
LL sumw=0,sumv=0;
for(int i=1;i<=n;i++)
{
LL w;
scanf("%lld",&w);
sumw+=(LL)i*w;
field[i].weight=w;
field[i].num=i;
}
for(int i=1;i<=n;i++)
{
LL v;
scanf("%lld",&v);
sumv+=(LL)v*i;
field[i].value=v;
field[i].pos=(double)field[i].value/field[i].weight;
}
if(sumw<=m) {
cout<<sumv<<endl;
continue;
}
//求后缀和
sort(field+1,field+n+1,cmp); //按照性价比排序
memset(sum,0,sizeof(sum));
for(int i=n;i>=1;i--)
sum[i]=sum[i+1]+field[i].value*field[i].num;
dfs(1,0,m);
cout<<ans<<endl;
}
return 0;
}
//dfs搜索剪枝+后缀和预处理
//首先利用性价比贪心,单位质量的价值越高则性价比越高
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
int n;
LL m,ans; //m为总重量,ans为最优解
LL sum[200];
struct maze{
LL weight,value;
double pos;
int num; //钻石数量
};
maze field[200];
bool cmp(maze a,maze b)
{
return a.pos>b.pos;
}
void dfs(int x,LL now_value,LL now_weight)
{
ans=max(ans,now_value); //更新最优解
if(now_weight<=0||x>n) return;
if(now_value+sum[x]<=ans) return; //如果当前的价值加上其余钻石的所有价值<=ans,则剪枝
double best=field[x].pos;
if(now_value+(LL)ceil(now_weight*best)<=ans) return; //剩下的重量全部装性价比最高的钻石,如果得到的价值小于此时已经得到的价值,则剪枝
for(int i=field[x].num;i>=0;i--) //先选择性价比较高的箱子
{
if(now_weight<field[x].weight*i) continue;
dfs(x+1,now_value+field[x].value*i,now_weight-field[x].weight*i);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d%lld",&n,&m);
LL sumw=0,sumv=0;
for(int i=1;i<=n;i++)
{
LL w;
scanf("%lld",&w);
sumw+=(LL)i*w;
field[i].weight=w;
field[i].num=i;
}
for(int i=1;i<=n;i++)
{
LL v;
scanf("%lld",&v);
sumv+=(LL)v*i;
field[i].value=v;
field[i].pos=(double)field[i].value/field[i].weight;
}
if(sumw<=m) {
cout<<sumv<<endl;
continue;
}
//求后缀和
sort(field+1,field+n+1,cmp); //按照性价比排序
memset(sum,0,sizeof(sum));
for(int i=n;i>=1;i--)
sum[i]=sum[i+1]+field[i].value*field[i].num;
dfs(1,0,m);
cout<<ans<<endl;
}
return 0;
}
相关文章推荐
- poj 3321 Apple Tree DFS时间戳预处理+树状数组
- POJ 3900 The Robbery(dfs)
- 度限制最小生成树 POJ 1639 贪心+DFS+prim
- POJ 3900 The Robbery (dfs暴搜+剪枝)
- POJ 2718 Smallest Difference(DFS或者贪心)
- POJ-2688:Cleaning Robot(bfs预处理+dfs)
- POJ 2004 Mix and Build (预处理+dfs)
- POJ 1699 Best Sequence (DFS+预处理)
- POJ-1743:Musical Theme(后缀数组加高度数组的应用以及预处理)
- [贪心+后缀数组] poj 3623 Best Cow Line, Gold
- POJ 1699 Best Sequence (DFS+预处理)
- POJ 3110 Jenny's First Exam (二分 + 树状数组 + 贪心 + 预处理年份)
- POJ 2034 Anti-prime Sequences(素数预处理+DFS回溯)
- POJ 1328 Radar Installation(预处理贪心)
- POJ - 3900 The Robbery (DFS+暴力剪枝)
- poj 3900 The Robbery(dfs+剪枝,不是背包)
- POJ 2431 Expedition (贪心 + 优先级队列)
- POJ 2774 Long Long Message 后缀数组/后缀自动机
- poj 2907 Collecting Beepers (dfs)
- poj3009(dfs)