码迷,mamicode.com
首页 > 其他好文 > 详细

01背包问题的及其优化

时间:2018-07-14 10:20:37      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:bsp   class   滚动数组   col   时间复杂度   code   cin   algorithm   i++   

有N件物品和一个容量为C的背包,第i件物品的费用是c[i],价值是w[i],求将若干件物品放入背包所能够获得的最大价值。

每种物品只有一件,可以选择放或者是不放

使用f(i,v)表示前i件物品恰好放入一个容量为v的背包所能获得的最大价值

状态转移方程:

f(i,v)=max{f(i-1,v),f(i-1,v-c[i])+w[i]}

时间复杂度为O(N*V),空间复杂度可以优化为O(V),即采用滚动数组的形式,与完全背包的实现相比较,这里是逆推,完全背包是正推

 f(v)=max{f(v),f(v-c[i])+w[i]}

首先我们给出第一个状态转移方程的实现:

int f[maxn][maxv];
int ans=0;
void dp()
{
    for(int i=1;i<=N;i++)
    for(int j=1;j<=V;j++)
    {
        if(v[i]<=j)
            f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
        else
            f[i][j]=f[i-1][j];
    }
    ans=f[N][V];
}

可以看到循环变量是很好写的

接下来我们给出滚动数组形式转移方程的实现:

int f2[maxv];
void dp2()
{
    for(int i=1;i<=N;i++)
    for(int j=V;j>=0;j--)
    {
        if(v[i]<=j)
            f2[j]=max(f2[j],f2[j-v[i]]+w[i]);
    }   
    ans=f2[V];
} 

这种方法虽然省空间,但是中间结果都被覆盖掉了

最后我们给出一个完整的代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=1005;
 5 const int maxv=1005;
 6 int N,V;
 7 int v[maxn],w[maxn];
 8 int f[maxn][maxv];
 9 int ans=0;
10 void dp()
11 {
12     for(int i=1;i<=N;i++)
13     for(int j=1;j<=V;j++)
14     {
15         if(v[i]<=j)
16             f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
17         else
18             f[i][j]=f[i-1][j];
19     }
20     ans=f[N][V];
21 }
22 int f2[maxv];
23 void dp2()
24 {
25     for(int i=1;i<=N;i++)
26     for(int j=V;j>=0;j--)
27     {
28         if(v[i]<=j)
29             f2[j]=max(f2[j],f2[j-v[i]]+w[i]);
30     }   
31     ans=f2[V];
32 } 
33 int main()
34 {
35     cin>>V>>N;
36     for(int i=1;i<=N;i++)
37         cin>>v[i]>>w[i];
38     dp2();
39     cout<<ans;
40     return 0;
41 }
42  

 

01背包问题的及其优化

标签:bsp   class   滚动数组   col   时间复杂度   code   cin   algorithm   i++   

原文地址:https://www.cnblogs.com/aininot260/p/9308558.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!