【C++背包】超级背包大集合

啊哈,经典的背包问题讲完了,这次呢,我们来总结一下背包问题,并整理程序。

总结

背包问题思路,就是将每一种放进去的情况都列举出来,并比较得到最优值,所以,就能求出最大值。这就是为什么背包问题中动态规划比普通递归要快,就是因为普通递归重复求了很多数值,而动态规划正好相反,把所有值存起来,对比值,求出,一般递归的时间复杂度是指数级,而动态规划基本上是平方级。

整理程序

(1) 01普通背包问题

#include<iostream>
#include<cstdio>
using namespace std;
int thing[1000001][3];         //重量(w)是thing[?][0],价值(c)是thing[?][1],f是thing[?][3] 
int max(int a,int b)
{
  return a>b? a:b;
}
int main()
{
  int n,V;
  cin>>V>>n;
    for(int i=1;i<=n;i++) cin>>thing[i][0]>>thing[i][1];
  for(int i=1;i<=n;i++)
  for(int v=V;v>=thing[i][0];v--)
  {
   	thing[v][2]=max(thing[v][2],thing[v-thing[i][0]][2]+thing[i][1]);
   }
    cout<<thing[V][2];
     return 0;
}

(2)完全背包问题

#include<iostream>
#include<cstdio>
using namespace std;
int thing[1000001][3];         //如有数据内容不懂,请看上篇文章
int max(int a,int b)
{
 return a>b? a:b;
}
int main()
{
 int n,V;
 cin>>V>>n;
 for(int i=1;i<=n;i++) cin>>thing[i][0]>>thing[i][1];
  for(int i=1;i<=n;i++)
  for(int v=thing[i][0];v<=V;v++)
  {
   thing[v][2]=max(thing[v][2],thing[v-thing[i][0]][2]+thing[i][1]);
  }
 cout<<thing[V][2];
 return 0;
}

(3)多重背包问题

#include<cstdio>
int v[10001],w[10001];
int f[6001];
int n,m,n1;
int max(int a,int b)
{
 return a>b?a:b;
}
int main()
{
 scanf("%d%d",&n,&m);
 for(int i=1;i<=n;i++)
  {
  int x,y,s,t=1;
  scanf("%d%d%d",&x,&y,&s);
  while (s>=t)
  {
   v[++n1]=x*t;
   w[n1]=y*t;
   s-=t;
   t*=2;
  }
  v[++n1]=x*s;
  w[n1]=y*s;                             //把s以2的指数分堆:1,2,4,...,2^(k-1),s-2^k+1;
 }
 for(int i=1;i<=n1;i++)
  for(int j=m;j>=v[i];j--)
   f[j]=max(f[j],f[j-v[i]]+w[i]); 
 printf("%d",f[m]);
    return 0;

(4)混合背包

#include<iostream>
using namespace std;
int f[1000001],n[1000001],w[1000001],c[1000001];

int main()
{
	int N,V;
	cin>>V>>N;
	for(int i=1;i<=N;i++)
		cin>>w[i]>>c[i]>>n[i];
	for(int i=1;i<=N;i++)
	{
		if(n[i]!=0)
			for(int j=1;j<=n[i];j++) //最多多少个
				for(int v=V;v>=w[i];v--)
					f[v]=max(f[v],f[v-w[i]]+c[i]);
		else
			for(int v=w[i];v<=V;v++)
 				f[v]=max(f[v],f[v-w[i]]+c[i]);
 	}
 	int max=-99999999;
 	for(int i=1;i<=V;i++) max=max<f[i]? f[i]:max;
 	cout<<max;
 	return 0;
 }

(5)二维费用的背包问题

#include<cstdio>
#include<cstring>
using namespace std;
int v, u, k;
int a[1001], b[1001], c[1001];
int f[101][101];
int main()
{
    memset(f,127,sizeof(f));
    f[0][0] = 0;
    scanf("%d%d%d",&v,&u,&k);
    for (int i = 1; i <= k; i++)
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
    for (int i = 1; i <= k; i++)
      for (int j = v; j >= 0; j--)
        for (int l = u; l >= 0; l--)
        {
           int t1 = j+ a[i],t2 = l + b[i];
           if (t1 > v)  t1 = v;                        //若氮、氧含量超过需求,可直接用需求量代换,
           if (t2> u)  t2 = u;
           if (f[t1][t2] > f[j][l] + c[i])  f[t1][t2] = f[j][l] + c[i];
        }
    printf("%d",f[v][u]);
    return 0;
}

(6)分组背包

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int f[5000],c[5000],w[5000],a[5000][5000],i,j,n,m,s,k,t,p;
int main ()
{
 cin>>n>>m>>t;
 for (i=1; i<=m; i++)
   {
   cin>>w[i];
   cin>>c[i];
   cin>>p;
   a[p][0]++;
   a[p][a[p][0]]=i;
   }
 for (k=1; k<=t; k++)  
   for (i=n; i>=0; i--)
     for (j=1; j<=a[k][0]; j++)
       if (i>=w[a[k][j]])
         f[i]=max(f[i],f[i-w[a[k][j]]]+c[a[k][j]]);
 cout<<f[n];
 return 0; 
}

好了,背包问题到此结束,也希望大家多多学习掌握!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Microsoft Visual C++ Redistributable(系统运行库,简称MSVC,VB/VC)是Windows操作系统应用程序的基础类型库组件。此版Visual C 运行库合集包(VisualCppRedist),是由国外My Digital Life论坛@abbodi1406改装而成,整合所有版本Visual C 组件,支持静默参数,自动安装所有库,装机必备。用于最新Microsoft Visual C ++可再发行运行时的AIO重新打包,而没有原始安装包膨胀,由国外My Digital Life论坛@abbodi1406改装而成,整合所有版本Visual C ++组件,支持静默参数,该过程由Windows命令脚本处理,该脚本默认情况下隐藏在后台运行,在安装之前,该脚本将检查并删除现有的不兼容的Visual C ++运行时,包括原始EXE或MSI安装程序,或较旧的MSI软件包版本,卸载选项/脚本将删除所有检测到的VC ++运行时(UCRT除外),Windows XP支持部分功能,该软件包将安装和检测最新的运行时版本,但不会检查和删除不兼容的版本。您可以使用7-zip或WinRar将安装程序文件解压缩到短路径,然后以管理员身份运行Installer.cmd,此版Visual C++运行库合集包(VisualCppRedist),自动安装所有库,装机必备。 VisualCppRedist AIO Microsoft Visual Basic/C++ Runtime (x86/x64) Microsoft C Runtime Library (2002: 7.0.9975.0) Microsoft C Runtime Library (2003: 7.10.6119.0) Microsoft Visual C++ Redistributables (x86/x64) Microsoft Visual C++ 2005 Redistributable – 8.0.61187 Microsoft Visual C++ 2008 Redistributable – 9.0.30729 Microsoft Visual C++ 2010 Redistributable – 10.0.40219 Microsoft Visual C++ 2012 Redistributable – 11.0.61135 Microsoft Visual C++ 2013 Redistributable – 12.0.40664 Microsoft Visual C++ 2015 Redistributable – 14.10.25008 Microsoft Visual C++ 2005-2019 Redistributable - 14.28.29812 Microsoft Visual Studio 2010 Tools for Office Runtime (x86/x64) 静默参数 VisualCppRedist_AIO_x86_x64.exe /ai -自动静默安装所有,不显示任何输出。 /y -自动安装所有,有安装界面进度显示。 /aiM -自选安装所有,安装每个版本有提取对话框,并确认询问。 /aiU -自动卸载所有,卸载每个版本有提取对话框,并确认询问。 /aiA -自动静默安装所有,但隐藏ARP项。 /aiR -自动静默卸载所有。 /ai5 -自动静默仅安装Microsoft Visual C 2005。 /ai8 -自动静默仅安装Microsoft Visual C 2008。 /aiX -自动静默仅安装Microsoft Visual C 2010。 /ai2 -自动静默仅安装Microsoft Visual C 2012。 /ai3 -自动静默 /ai9 -自动静默仅安装Microsoft Visual C 2019。 /aiT -自动静默仅安装Microsoft Visual Studio 2010。 /aiE -自动静默仅安装额外的Microsoft Visual Basic/C 。 /aiV -自动静默仅安装Microsoft C Runtime Library基础库。 /aiH -系统“卸载程序”界面中“自动隐藏已经安装”项。 /aiP -系统“卸载程序”界面中“手动隐藏或显示已经安装”项。 /aiC -完全自动被动模式。安装所有,但UCRT KB3118401除外。 /aiD -调试模式,创建VCpp_debug.log而不安装/卸载任何组件。 /gm2 -用于禁用所有其它开关的提取解压对话框的可选开关

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值