zoukankan      html  css  js  c++  java
  • 01背包问题

    01背包

    有n种物品,背包重量为V,接下来有每个背包的重量w[i],价值v[i],求最大的总价值。

    这是01背包的基本样式,

    首先分析问题,有两种状态,放还是不放,显然得出了我们第一个dp方程

    dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])

    表示前i个已经放了重量为j的物品所能获得的最大价值。

    咱们继续想想,数据过大怎么办

    于是想想优化空间复杂度

    得到了新的dp方程

    dp[j]=max(dp[j],dp[j-w[i]]+v[i])       (j=V;j>=0;j--)

    为什么这是对的呢?

    显然在递推的过程中,小的状态并不影响大的状态,因为根本还没有计算到那一步

    要保证计算第i步时,是由第i-1步推出的

    所以

    贴代码

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <cstring> 
    using namespace std;
    int n,V,dp[1010],v[1005],w[1005];
    int main()
    {
        scanf("%d %d",&V,&n); 
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&w[i],&v[i]);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=V;j>=w[i];j--)
            {
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
        printf("%d
    ",dp[V]);
    }

    我还是太蒻了

    例题(洛谷1060 开心的金明) https://www.luogu.org/problemnew/show/P1060

    太简单了,贴代码

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    int dp[30030];
    int w[30];
    int c[30];    
    int i,j;
    int n,m;
    int main() 
    {
        scanf("%d %d",&m,&n);
        for (i=1;i<=n;i++) 
            scanf("%d%d",&w[i],&c[i]);
        for (i=1;i<=n;i++) 
        {
            for (j=m;j>=w[i];j--) 
            {
                dp[j]=max(dp[j],dp[j-w[i]]+w[i]*c[i]);
            }
        }
        printf("%d
    ",dp[m]);
        return 0 ;
    }

     题目:

    这题也十分简单

    简单的01背包,ai,bi,如果更优及更新

    上代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=10005;
    int dp[N],wa[N],va[N],wb[N],vb[N];
    int n,v;
    int main()
    {
        scanf("%d %d",&n,&v);
        for(int i=1;i<=n;i++)
            scanf("%d %d %d %d",&wa[i],&va[i],&wb[i],&vb[i]);
        for(int i=1;i<=n;i++)
            for(int j=v;j>=0;j--)
            {
                if(j>=wa[i])
                    dp[j]=max(dp[j],dp[j-wa[i]]+va[i]);
                if(j>=wb[i])
                    dp[j]=max(dp[j],dp[j-wb[i]]+vb[i]);
            }
        printf("%d
    ",dp[v]);
        return 0;
    }
  • 相关阅读:
    进程管理
    磁盘管理
    用户组管理
    Idea 导入(import)项目和打开(open)项目的区别
    SqlServer--转换varchr值‘2993296307’时溢出了整数列 和 修改 字段类型
    C#--Winform--图标控件Chart详解
    SqlServer--存储过程--自定义存储过程
    SqlServer--存储过程--系统和扩展存储过程(不常用)
    SqlServer--视图
    C#--SqlServer--sql语句拼接和带参数的SQL语句
  • 原文地址:https://www.cnblogs.com/wzrdl/p/9771111.html
Copyright © 2011-2022 走看看