一:0-1背包问题


#include<iostream>
#include<algorithm>
#include<cstring>
const int maxn=100;
using namespace std;
int w[maxn];
int p[maxn];
int x[maxn];
int c[maxn][maxn];
int kanpsack_1(int n,int m){for(int i=0;i<=m;i++){c[0][i]=0;}for(int j=0;j<=n;j++){c[j][0]=0;}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(j<w[i]){c[i][j]=c[i-1][j];}else{c[i][j]=max(c[i-1][j-w[i]]+p[i],c[i-1][j]);}}}int j=m;for(int i=n;i>0;i--){if(c[i][j]>c[i-1][j]){x[i]=1;j-=w[i];}else{x[i]=0;}}return c[n][m];
}
int main(){int n,W;int we;//总重量 cin>>n;cin>>we;for(int i=1;i<=n;i++){cin>>w[i];} for(int i=1;i<=n;i++){cin>>p[i];}int WE=kanpsack_1(n,we);for(int i=1;i<=n;i++){cout<<x[i]<<" ";}   cout<<endl;cout<<WE<<endl;return 0;
}
/*
5
10
2 2 6 5 4
6 3 5 4 6
*/
深搜0-1背包:记忆化搜索
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int value[1005];
int valume[1005];
int dp[1005][1005];
int n,v;
int dfs(int index,int c){int res=0;if(dp[index][c]>=0)return dp[index][c];if(index>n)return dp[index][c]=0;if(c<valume[index]){res=dfs(index+1,c);}else{res=max(dfs(index+1,c),dfs(index+1,c-valume[index])+value[index]);}dp[index][c]=res;return res;
}
int main(){int t;cin>>t;while(t--){cin>>n>>v;for(int i=1;i<=n;i++){cin>>value[i]; }for(int i=1;i<=n;i++){cin>>valume[i];}int sum=dfs(1,v);cout<<sum<<endl;}return 0;
}
非记忆化深搜
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int value[1005];
int valume[1005];
int n,v;
int dfs(int index,int c){int res=0;if(index>n)return 0;if(c<valume[index]){res=dfs(index+1,c);}else{res=max(dfs(index+1,c),dfs(index+1,c-valume[index])+value[index]);}return res;
}
int main(){int t;cin>>t;while(t--){cin>>n>>v;for(int i=1;i<=n;i++){cin>>value[i]; }for(int i=1;i<=n;i++){cin>>valume[i];}int sum=dfs(1,v);cout<<sum<<endl;}return 0;
}


二:多重背包:
思路:将多重背包转换为0-1背包。
状态转移方程为 dp[i+1][j]=max(dp[i][j-w[i]*k])+v[k] k=(0…g[i]);g[i]表示物品i共有几个。

方法一:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int W,n;
int w[105],v[105],g[105];
int dp[205][20005];
int main(){int T;scanf("%d",&T);while(T--){memset(dp,0,sizeof(dp));scanf("%d%d",&W,&n);for(int i=0;i<n;i++){scanf("%d%d%d",&w[i],&v[i],&g[i]);//分别表示物品的重量,价值,这种物品的数量}for(int i=0;i<n;i++)for(int j=0;j<=W;j++){dp[i+1][j]=dp[i][j];for(int k=1;k<=g[i];k++)if(j>=k*w[i])    dp[i+1][j]=max(dp[i+1][j],dp[i][j-w[i]*k]+v[i]*k);}printf("%d\n",dp[n][W]);}return 0;
}

方法二:转化为01背包
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{int cost;int weight;int nums;
}num[1000005];
int sum_cost,kind;
int dp[1005];
int main(){int t;cin>>t;while(t--){int cnt=0;cin>>sum_cost>>kind;for(int i=1;i<=kind;i++){int x,y,z;//分别表示物品的重量,价值,这种物品的数量cin>>x>>y>>z;for(int j=1;j<=z;j++){num[cnt].cost=x;num[cnt++].weight=y;}}for(int i=0;i<cnt;i++){for(int j=sum_cost;j>=num[i].cost;j--){dp[j]=max(dp[j],dp[j-num[i].cost]+num[i].weight);}}cout<<dp[sum_cost]<<endl;}return 0;
}
方法三:记忆化搜索
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{int cost;int weight;int nums;
}num[105];
int sum_cost,kind;
int dp[105][10005];
int solve(int index,int sumcost){int temp;if(dp[index][sumcost]>0)return dp[index][sumcost];if(index>=kind||sumcost==0)return dp[index][sumcost]=0;else if(num[index].cost>sumcost){temp=solve(index+1,sumcost);}else{for(int k=0;k<=num[index].nums&&k*num[index].cost<=sumcost;k++){temp=max(solve(index+1,sumcost),solve(index+1,sumcost-num[index].cost*k)+num[index].weight*k);}}dp[index][sumcost]=temp;return temp;
}
int main(){int t;cin>>t;while(t--){cin>>sum_cost>>kind;for(int i=1;i<=kind;i++){cin>>num[i].cost>>num[i].weight>>num[i].nums;}int sum=solve(1,sum_cost);cout<<sum<<endl;}return 0;
}
方法四:转换为二进制方法
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int W,n;
int w[2005],v[2005];
int dp[20005];
int main()
{int T;scanf("%d",&T);while(T--){memset(dp,0,sizeof(dp));scanf("%d%d",&W,&n);int cnt=0;int a,b,c;for(int i=0;i<n;i++){scanf("%d%d%d",&a,&b,&c);//分别表示物品的重量,价值,这种物品的数量int e=1;while(e<c){w[cnt]=a*e;v[cnt]=b*e;cnt++;c-=e;e*=2;}w[cnt]=a*c;v[cnt]=b*c;cnt++;}for(int i=0;i<cnt;i++)for(int j=W;j>=w[i];j--)dp[j]=max(dp[j],dp[j-w[i]]+v[i]);printf("%d\n",dp[W]);}return 0;
}

三:回溯法求解0-1背包

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxx=105;
const int inf=0x3f3f3f3f;
int w[maxx];//物品的重量
int v[maxx];//物品的价值
int cp;//当前的价值
int cw;//当前的重量
int c;//重量的上限
int bestp;//最后的最大价值
int bestx[maxx];//记录被装入背包的物品
int x[maxx];//记录当前装入背包的物品
int n,m;
void init(){cw=0;cp=0;;memset(w,0,sizeof(w));memset(v,0,sizeof(v));memset(bestx,0,sizeof(bestx));
}
int Bound(int i){//计算上界 ,存在比当前可能的更优解 int cleft=c-cw;int b=cp;while(i<=n&&w[i]<=cleft){cleft-=w[i];b+=v[i];i++;}if(i<=n){b+=v[i]/w[i]*cleft;}return b;
}
void BackTrack(int t){if(t>n){for(int j=1;j<=n;j++){bestx[j]=x[j];}bestp=cp;return ;}if(cw+w[t]<=c){x[t]=1;cw+=w[t];cp+=v[t];BackTrack(t+1);//进入左子树 cw-=w[t];cp-=v[t];}if(Bound(t+1)>bestp){//进入右子树 x[t]=0;BackTrack(t+1);}
}
int main(){while(scanf("%d %d",&n,&c)!=EOF){for(int i=1;i<=n;i++){scanf("%d",&w[i]);}for(int i=1;i<=n;i++){scanf("%d",&v[i]);}BackTrack(1);cout<<"最大价值: "<<bestp<<endl; cout<<"可以被装入的物品: "; for(int i=1;i<=n;i++){if(bestx[i]==1){cout<<i<<" ";} }cout<<endl; }return 0;
}

这是我自己在做题中总结出来的,如果存在什么问题或者错误,请指出!谢谢!

背包问题(多重背包+0-1背包)相关推荐

  1. 浅说——九讲背包之01背包

    所谓九讲,也就是: 0/1背包 0/1背包降维 完全背包 多重背包(二进制优化) 混合背包 二维费用背包 分组背包 有依赖的背包 背包的方案总数\背包的具体方案路径 0/1背包: [问题描述](经典) ...

  2. 背包问题教程-01背包,完全背包,多重背包,混合背包 收藏

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有 ...

  3. 01背包、完全背包、多重背包问题的C++实现及路径记录

    这里主要实现路径记录,只求最值问题移步 01背包.完全背包.多重背包问题的C++实现 以下均打印输出路径,即装入背包的物品序号,和最大值. 01背包问题 #include <iostream&g ...

  4. 01背包、完全背包、多重背包问题的C++实现

    01背包问题 容量为10的背包,有5种物品,每种物品只有一个,其重量分别为5,4,3,2,1,其价值分别为1,2,3,4,5. 设计算法,实现背包内物品价值最大. 代码如下(输出14) #includ ...

  5. 01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,背包问题求方案数

    1 01背包问题 有 NNN 件物品和一个容量是 VVV 的背包.每件物品只能使用 一次. 第 iii 件物品的体积是 viv_ivi​,价值是 wiw_iwi​.求解将哪些物品装入背包,可使这些物品 ...

  6. python 完全背包问题_动态规划——背包问题python实现(01背包、完全背包、多重背包)...

    参考: 描述: 有N件物品和一个容量为V的背包. 第i件物品的体积是vi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包流量,且总价值最大. 二维动态规划 f[i][j] 表示只 ...

  7. 背包问题(01背包,完全背包,多重背包(朴素算法二进制优化))

    写在前面:我是一只蒟蒻~~~ 今天我们要讲讲动态规划中~~最最最最最~~~~简单~~的背包问题 1. 首先,我们先介绍一下  01背包 大家先看一下这道01背包的问题   题目   有m件物品和一个容 ...

  8. C++ 背包问题——多重背包

    C++背包问题好久没更新了,过来讲一讲背包问题中的多重背包: 1.多重背包定义: 要想了解多重背包,首先要了解01背包(会的也看一看),多重背包就是在01背包的基础上,增加了物品的个数,这一点要区别于 ...

  9. 背包问题详解:01背包、完全背包、多重背包

    参考链接: http://www.cnblogs.com/fengty90/p/3768845.html http://blog.csdn.net/mu399/article/details/7722 ...

  10. 背包问题基础模型深度总结-文长慎入(01背包,完全背包,多重背包)

    先等一下,字多预警,密集恐惧症慎入,喂,你,就是你,小板凳搬好了吗,站久了可是会腿酸的 无节操地王婆卖瓜一下, 本文 深度好文 目录 先扯两句 0-1背包 其它类似的状态定义 1 2 小结 3  记忆 ...

最新文章

  1. 基于web的可定制数据填报平台
  2. leetcode算法题--Flood Fill
  3. vagrant安装及使用方法
  4. python运算符讲解_3.Python运算符详解
  5. C语言的条件编译#if, #elif, #else, #endif、#ifdef, #ifndef
  6. C# 8: 默认接口方法
  7. 技术达人“创造营”官宣:Microsoft Learn 学习平台C位出道
  8. AtCoder Beginner Contest 084(AB)
  9. 阿里云SLB负载均衡与使用SSL域名证书
  10. Oracle统计信息中的Pending Statistics
  11. (并查集 建立关系)Parity game -- POJ -1733
  12. python写数据库中间件_python3开发进阶-Django框架的中间件的五种用法和逻辑过程...
  13. 现如今有一个很有意思的现象,不管是工厂还是经销商
  14. ElasticSearch基础之批量操作(mget+mbulk)
  15. Netty框架多人聊天案例,代码示例
  16. Winform控件学习笔记【第四天】——WebBrowser
  17. Javascript特效:不断在页面跑的星星
  18. 分享10个优秀的技术栈社区
  19. 半条命2服务器无响应,半条命2游戏常见问题解决方法
  20. sourceinsight 的好处_代码阅读神器——Sourceinsight

热门文章

  1. 通俗易懂的TCP里面的三次握手以及四次挥手
  2. MATLAB_8-边缘检测_黄晓明圈出人脸
  3. 技术08期:十大经典数据挖掘算法【PageRank篇】
  4. 怎么定义图像的质量?如何评价图像的质量?
  5. SLAM和三维重建有什么区别?
  6. Sqoop数据迁移原理及基本框架
  7. SQL SERVER特殊行转列案列一则
  8. Action Golf 四个魔法球实战训练系列_huatuo_新浪博客
  9. XSL 扩展样式表语言(EXtensible Stylesheet Language)
  10. MySQL数据库MyISAM存储引擎转为Innodb