各种方法优化背包
对应试题为
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优化