• 动态规划-背包问题


    01背包

    题意

     算法思路

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 1005;
    int v[MAXN];    // 体积
    int w[MAXN];    // 价值 
    int f[MAXN][MAXN];  // f[i][j], j体积下前i个物品的最大价值 
    
    int main() 
    {
        int n, m;   
        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 = 1; j <= m; j++)
            {
                //  当前背包容量装不进第i个物品,则价值等于前i-1个物品
                if(j < v[i]) 
                    f[i][j] = f[i - 1][j];
                // 能装,需进行决策是否选择第i个物品
                else    
                    f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
            }           
    
        cout << f[n][m] << endl;
    
        return 0;
    }

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    int N,V;
    int v[maxn],w[maxn];
    int dp[maxn];
    int main()
    {
        int i,j;
        cin>>N>>V;
        for(i=1;i<=N;i++)
            cin>>v[i]>>w[i];
        for(i=1;i<=N;i++)
        {
            for(j=V;j>=v[i];j--)
                dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
        }
        cout<<dp[V]<<endl;
        return 0;
    }

    完全背包

    题意

    算法思路

     

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    int N,V;
    int v[maxn],w[maxn];
    int dp[maxn];
    
    int main()
    {
        int i,j;
        cin>>N>>V;
        for(i=0;i<N;i++)
            cin>>v[i]>>w[i];
        for(i=0;i<N;i++)
        {
            for(j=v[i];j<=V;j++)
                dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
        }
        cout<<dp[V];
        return 0;
    }

    多重背包

    题意

     算法思路

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    int N,V;
    int w[maxn],v[maxn],s[maxn];
    int dp[maxn][maxn];
    int main()
    {
        int i,j,k;
        cin>>N>>V;
        for(i=1;i<=N;i++)
            cin>>v[i]>>w[i]>>s[i];
        for(i=1;i<=N;i++)
        {
            for(j=0;j<=V;j++)
            {
                for(k=0;k<=s[i]&&k*v[i]<=j;k++)
                    dp[i][j]=max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
            }
        }
        cout<<dp[N][V]<<endl;
        return 0;
    }

    若是数据范围有所调整

    则该方法不可使用,可使用01背包+二进制优化的方法

    #include<bits/stdc++.h>
    using namespace std;
    const int n=12010,m=2010;
    int N,V;
    int v[n],w[n];
    int f[m];
    
    int main()
    {
        int i,j;
        cin>>N>>V;
        int cnt=0;
        for(i=0;i<N;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
    
            int k=1;
            while(k<=c)
            {
               cnt++;
               v[cnt]=a*k;
               w[cnt]=b*k;
               c-=k;
               k*=2;
            }
            if(c>0)
            {
                cnt++;
                v[cnt]=a*c;
                w[cnt]=b*c;
            }
        }
        N=cnt;
        for(i=1;i<=N;i++)
        {
            for(j=V;j>=v[i];j--)
                f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
        cout<<f[V]<<endl;
        return 0;
    }

    分组背包

    题意

    算法思路

    #include<bits/stdc++.h>
    using namespace std;
    int s[110];
    int v[110][110],w[110][110];
    int f[110];
    
    int main()
    {
        int i,j,k;
        int N,V;
        cin>>N>>V;
        for(i=0;i<N;i++)
        {
            cin>>s[i];
            for(j=0;j<s[i];j++)
                cin>>v[i][j]>>w[i][j];
        }
        for(i=0;i<N;i++)
        {
            for(j=V;j>=0;j--)
            {
                for(k=0;k<s[i];k++)
                {
                    if(j>=v[i][k])
                        f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
                }
            }
        }
        cout<<f[V]<<endl;
        return 0;
    }
  • 相关阅读:
    CSS 3列等高
    CSS分列等高
    jQuery函数
    JQuery解析JSON数据
    2020-09-25:rust中Point是结构体类型,【let p1=Point{x:25,y:25};let p2=p1;】请问p1和p2是同一个对象吗?
    2020-09-24:jvm监控系统是通过jmx做的么?
    2020-09-23:TCP头部信息有哪些?
    2020-09-22:已知两个数的最大公约数和最小公倍数,并且这两个数不能是最大公约数和最小公倍数本身。如何判断这两个数是否存在?
    2020-09-21:已知最大公约数和最小公倍数,如何判断这两个数是否存在?
    2020-09-20:如何判断一个数是质数?
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/14418651.html
Copyright © 2020-2023  润新知