动态规划与其他算法比较,大大减少了计算量,丰富了计算的结果,最适合解决最优解问题。今天讲的是背包问题。
1、0-1背包:
简介:有n件物品,总空间是w,前i件的容量是w[i],前i件的价值是v[i],那么所获取的最大容量是dp[w].
代码如下:
#include<stdio.h> #include<string.h> int f[201000]; int w[210000]; int v[210000]; int max(int n,int m) { if(n>m) return n; else return m; } int main() { int n,m; int i,j; while(~scanf("%d%d",&n,&m)) { memset(f,0,sizeof(f)); for(i=1;i<=n;i++) scanf("%d%d",&w[i],&v[i]); for(i=1;i<=n;i++) for(j=m;j>=w[i];j--) { int s=f[j-w[i]]+v[i]; f[j]=max(f[j],s); } printf("%d\n",f[m]); } return 0; }
2、完全背包:
简介:完全背包是有n种物品,总空间为w,每种的物品的件数是无限个,已知每种物品的容量为w[i],价值为v[i],如何满足最大价值。
代码如下:
#include <iostream> #include <algorithm> using namespace std; int a[600],b[600],dp[1000005]; int main() { int t,x,y,n; cin>>t; while(t--){ int w; cin>>w; //背包容量 cin>>n; for(int i=0;i<n;i++) cin>>b[i]>>a[i]; for(int i=0;i<=w;i++) //初始化分两种情况:1、如果背包要求正好装满则初始化 f[0] = 0, f[i]=INF;2、如果不需要正好装满 f[0~w] = 0; dp[i]=0; for(int i=0;i<n;i++) for(int j=b[i];j<=w;j++)//j表示背包容量 dp[j]=max(dp[j],dp[j-b[i]]+a[i]); // for(int i=1;i<=w;i++) cout<<dp[w]<<endl; } return 0; }
3、多重背包:
简介:多重背包就是0-1背包的扩展,0-1背包每一种物品一共有一件,多重背包每一种可能有多件,如一共有n种物品,每种物品的件数是bag[i],总空间是w,每一件容量是w[i],每一件价值是v[i].
代码如下:
#include<iostream> #include<string.h> #include <algorithm> int v[1000],w[1000],c[1000],dp[1000]; using namespace std; int main() { int T; cin>>T; while(T--) { memset(dp,0,sizeof(dp)); int n,m; cin>>n>>m; for(int i=1;i<=m;i++) cin>>v[i]>>w[i]>>c[i]; for(int i=1;i<=m;i++) for(int k=1;k<=c[i];k++) for(int j=n;j>=v[i];j--) dp[j]=max(dp[j],dp[j-v[i]]+w[i]); cout<<dp[n]<<endl; } return 0; }