各种方法优化背包
对应试题为
HDU 5887 Herbs Gathering(背包问题的剪枝技巧)_搜索剪枝 在装满背包的前提下求最小的多余个数-CSDN博客
1:使用map进行优化
#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<int,ll>mp,tmp;
map<int,ll>::iterator it;
int main() {
int N,M,v,w;
ll ans;
while(~scanf("%d%d",&N,&M)) {
mp.clear();
mp[0]=0;
for(int i=1; i<=N; i++)
{
scanf("%d%d",&v,&w);
tmp.clear();//tmp为当前这一维,mp为上一维
for(it=mp.begin(); it!=mp.end(); it++)
//枚举上一维的状态
{
int x=it->first;
ll y=it->second;
if(tmp.find(x)==tmp.end())
//如果没有找到,则直接加入
tmp[x]=y;
else //否则取最优值
tmp[x]=max(tmp[x],y);
if(x+v<=M)
tmp[x+v]=max(tmp[x+v],y+w);
}
mp.clear();
ll ans=-1;
//这一段进行筛选工作,将体积大,但是权值又小的状态丢掉
//例如 体积 权值
// 2 5
// 3 4
// 7 9
// 将第一个和第三个加入mp,第二个它的存在是没有意义的
for(it=tmp.begin(); it!=tmp.end(); it++)
if(it->second>ans)
{
mp[it->first]=it->second;
ans=it->second;
}
if(i==N) printf("%lld\n",ans);
}
}
return 0;
}
2:dfs加卡时
const int N=100+5;
int n,m;
double t;
int i,j,k;
ll ans;
struct Node
{
ll t,val;
double rate;
bool operator<(Node b){
return rate>b.rate;
}
}a[N];
bool judge(int id,ll sum,int time)//剪枝判断
{
for(int i=id;i<n;i++){
if(time>=a[i].t){ time-=a[i].t; sum+=a[i].val; }
else{ sum+=a[id].rate*(a[i].t-time); }
}
return sum>ans;
}
void DFS(int id,ll sum,int time)
//当前草药的编号,目前为止的价值 sum,剩余的时间
{
if( !judge(id,sum,time) ) return ;
if(sum+a[id].rate*time<ans) return ;
if(ans<sum) ans=sum;
if(id==n) return ;
if( a[id].t<=time ) DFS(id+1,sum+a[id].val,time-a[id].t);
DFS(id+1,sum,time);
}
int main()
{
//IOS;
while(sdd(n,m)==2){
for(i=0;i<n;i++){
cin>>a[i].t>>a[i].val;
a[i].rate=a[i].val*1.0/a[i].t;
}
sort(a,a+n);
ans=0;
DFS(0,0,m);
pld(ans);
}
//PAUSE;
return 0;
}
3:使用bitset优化

浙公网安备 33010602011771号