背包解法

首先是01背包的算法代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1005;
int f[N];
int v[N],w[N];
int n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>v[i]>>w[i];
    //背包处理
    for(int i=1;i<=n;i++)
    for(int j=m;j>=v[i];j--)
    f[j]=max(f[j],f[j-v[i]]+w[i]);
    cout<<f[m];
    return 0;
}

  然后是完全背包问题:

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1005;
int f[N];
int n,m;
int main()
{
    cin>>n>>m;
    int v,w;
    for(int i=1;i<=n;i++)
    {
        cin>>v>>w;
        for(int j=v;j<=m;j++)
        {
            f[j]=max(f[j],f[j-v]+w);
        }
    }
    cout<<f[m];
    return 0;
}

  多重背包问题:

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1005;
int f[N];
int v,w,s;
int n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>v>>w>>s;
        for(int j=m;j>=v;j--)
        {
            for(int k=1;k<=s&&j>=k*v;k++)
            f[j]=max(f[j],f[j-k*v]+k*w);
        }
    }
    cout<<f[m];
    return 0;
}

  多重背包优化(二进制):

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1005;
int f[N];
int v,w,s;
int n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>v>>w>>s;
        for(int j=m;j>=v;j--)
        {
            for(int k=1;k<=s&&j>=k*v;k++)
            f[j]=max(f[j],f[j-k*v]+k*w);
        }
    }
    cout<<f[m];
    return 0;
}

混合背包问题:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1005;
int f[N];
int n,m;
struct Thing
{
    int kind,v,w;
};
vector<Thing> things;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int v,w,s;
        cin>>v>>w>>s;
        if(s<=0)
        {
            things.push_back({-1,v,w});
        }
        else if(s==0)
        {
            things.push_back({0,v,w});
        }
        else
        {
            for(int k=1;k<=s;k*=2)
            {
                things.push_back({-1,v*k,w*k});
                s-=k;
            }
            if(s>0)things.push_back({-1,v*s,w*s});
        }
    }
    for(auto thing:things)
    {
        if(thing.kind<0)
        for(int j=m;j>=thing.v;j--)
        {
            f[j]=max(f[j],f[j-thing.v]+thing.w);
        }
        else
        {
            for(int j=thing.v;j<=m;j++)
            {
                f[j]=max(f[j],f[j-thing.v]+thing.w);
            }
        }
    }
    cout<<f[m];
    return 0;
}

二维费用:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=104;
int f[N][N];
int n,v,m;
int main()
{
    cin>>n>>v>>m;
    int a,b,c;
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b>>c;
        for(int j=v;j>=a;j--)
        for(int k=m;k>=b;k--)
        f[j][k]=max(f[j][k],f[j-a][k-b]+c);
    }
    cout<<f[v][m];
    return 0;
}

  

posted @ 2020-07-27 18:00  喜欢爬的孩子  阅读(121)  评论(0编辑  收藏  举报