c++背包问题

c++背包问题

动态规划和贪心中的五个背包问题,收集并整理出来放在这里。

0/1背包问题

0/1背包问题是一道动规的题,其题目意思就是每样物品只能取一个。二维表格中概括来说是上面位置的数&&上面的位置减物品质量这个数值后这个位子上的数加物品的价值比较哪个大,这里为了方便都转换为一维数组来做。(一样的)

#include <iostream>
using namespace std;
int dp[100];
int main()
{<!-- -->
 int n;
 int m;
 cin>>m>>n;
 int w[100];
 int c[100];
 for (int i=1;i<=n;i++)
 {<!-- -->
  cin>>w[i]>>c[i];
 }
 for (int i=1;i<=n;i++)
 {<!-- -->
  for (int j=1;j<=m;j++)
  {<!-- -->
   if (j>=w[i])
   {<!-- -->
    dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
   }
  }
 }
 cout<<dp[m];
 return 0;
}

其中w[]是体积,c[]是价值。

完全背包问题

完全,也就是物品可以取无限件。没什么差别,只是表格横向不一样(从小到大,从当前体积开始)

#include <bits/stdc++.h>
using namespace std;
int dp[1090];
int main()
{<!-- -->
 int n;
 int v;
 cin>>n>>v;
 int n1[1000];
 int v1[1000];
 for (int i=1;i<=n;i++)
 {<!-- -->
  cin>>n1[i]>>v1[i];
 }
 for (int i=1;i<=n;i++)
 {<!-- -->
  for (int j=n1[i];j<=v;j++)
  {<!-- -->
   dp[j]=max(dp[j],dp[j-n1[i]]+v1[i]);
  }
 }
 cout<<dp[v]<<endl;
 return 0;
}

n1[]是体积,v1[]是价值。

多重背包问题

无非是0/1背包多了一个数量控制罢了。

#include<iostream>
using namespace std;
int dp[1000];
int main()
{<!-- -->
 int N,V;
 cin>>N>>V;
 int v[1000],w[1000],s[1000];
 for (int i=1;i<=N;i++)
 {<!-- -->
  cin>>w[i]>>v[i]>>s[i];
 }
 for (int i=1;i<=N;i++)//商品种类的数量 
 {<!-- -->
  for (int j=V;j>=w[i];j--)//背包空间 
  {<!-- -->
   for (int k=1;k<=s[i]&&k*s[i]<=j;k++)//数量限制 
   {<!-- -->
    dp[j]=max(dp[j],dp[j-w[i]*k]+v[i]*k);
   }
  }
 }
 cout<<dp[V]<<endl;
 return 0;
 }

w[]是体积,v[]是价值,s[]是数量。

混合背包问题

三种混起来而已,我甭说了吧

#include <iostream>
using namespace std;
int dp[1000];
int main()
{<!-- -->
 int n,V;
 cin>>V>>n;
 int w[1000],v[1000],c[1000];
 for (int i=1;i<=n;i++)
 {<!-- -->
  cin>>w[i]>>v[i]>>c[i];
 }
 for (int i=1;i<=n;i++)
 {<!-- -->
  if (c[i]==1)
  {<!-- -->
   for (int j=V;j>=w[i];j--)
   {<!-- -->
    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
   }
  } 
  else if (c[i]==0)
  {<!-- -->
   for (int j=w[i];j<=V;j++)
   {<!-- -->
    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
   }
  }
  else if (c[i]>1)
  {<!-- -->
   for (int j=V;j>=w[i];j--)//背包空间 
   {<!-- -->
    for (int k=1;k<=c[i]&&k*w[i]<=j;k++)//数量限制 
    {<!-- -->
     dp[j]=max(dp[j],dp[j-w[i]*k]+v[i]*k);
    }
   }
  }
 }
 cout<<dp[V]<<endl;
 return 0;
}

贪心背包问题

前四种都是动规,这种是贪心哦。又叫小数背包问题。

#include <iostream>
//#include <algorithm>
#include <iomanip>
using namespace std;
int m,n;
struct node 
{<!-- -->
 int v,w;
 double k;
}a[1000];
bool cmp(node x,node y)
{<!-- -->
 return x.k>y.k;
}
int main()
{<!-- -->
 double sum=0;
 cin>>m>>n;
 for (int i=0;i<n;i++)
 {<!-- -->
  cin>>a[i].v>>a[i].w;
  a[i].k=a[i].v*1.0/a[i].w;
 }
// sort (a,a+n,cmp);
 for (int i=0;i<n-1;i++)
 {<!-- -->
  for (int j=i+1;j<n;j++)
  {<!-- -->
   if (a[i].k<a[j].k)
   {<!-- -->
    swap(a[i],a[j]);
   }
  }
 }
 for (int i=0;i<n;i++)
 {<!-- -->
  if (m>=a[i].w)
  {<!-- -->
   sum+=a[i].v;
   m-=a[i].w;
  }
  else
  {<!-- -->
   sum+=a[i].k*m;
   break;
  }
 }
 cout<<fixed<<setprecision(2)<<sum<<endl;
 return 0;
}

结构体中,v是价值,w是体积,k是性价比。

这五种背包,脑子和手都学废了吧(●’◡’●)。 点个赞再走呗~~~

posted @ 2021-01-12 16:41  刘桓湚  阅读(1086)  评论(0编辑  收藏  举报