zoukankan      html  css  js  c++  java
  • 背包 http://blog.csdn.net/insistgogo/article/details/8579597

    #include <iostream>
    using namespace std;
    
    const int N = 3;//物品个数
    const int V = 5;//背包最大容量
    int weight[N + 1] = {0,3,2,2};//物品重量
    int value[N + 1] = {0,5,10,20};//物品价值
    
    int f[N + 1][V + 1] = {{0}};
    
    int Max(int x,int y)
    {
    	return x > y ? x : y;
    }
    
    /*
    目标:在不超过背包容量的情况下,最多能获得多少价值
    
    子问题状态:f[i][j]:表示前i件物品放入容量为j的背包得到的最大价值
    
    状态转移方程:f[i][j] = max{f[i - 1][j],f[i - 1][j - weight[i]] + value[i]}
    
    初始化:f数组全设置为0
    */
    int Knapsack()
    {
    	//初始化
    	memset(f,0,sizeof(f));
    	//递推
    	for (int i = 1;i <= N;i++) //枚举物品
    	{
    		for (int j = 0;j <= V;j++) //枚举背包容量
    		{
    			f[i][j] = f[i - 1][j];
    			if (j >= weight[i])
    			{
    				f[i][j] = Max(f[i - 1][j],f[i - 1][j - weight[i]] + value[i]);
    			}
    		}
    	}
    	return f[N][V];
    }
    
    int main()
    {
    	cout<<Knapsack()<<endl;
    	system("pause");
    	return 1;
    }
    

      0-1背包问题为最基本的背包问题,她的实现主要包括 N,V,W[],C[],f[][],这五部分,背包问题为动态规划问题,其问题不难理解,但由于自己不甚了解,或者说是代码敲得不多,总是遗忘,所以要好好整理一下,在自己脑海里形成一个系统

    0-1背包问题首先要初始化数组,一般说来0-1背包都被初始化为0,它可以看作是一个二维的图,将图初始化为0,其次,要进行双重循环,外层循环是物品循环,内层循环是容量循环,不断根据状态转移方程,更新图中的数据

    注意一点,我们是由第 i - 1 次循环的两个状态推出 第 i 个状态的,而且 v  > v - weight[i],则对于第i次循环,背包容量只有当V..0循环时,才会先处理背包容量为v的状况,后处理背包容量为 v-weight[i] 的情况。

    具体来说,由于,在执行v时,还没执行到v - weight[i]的,因此,f[v - weight[i]]保存的还是第i - 1次循环的结果。即在执行第i次循环 且 背包容量为v时,此时的f[v]存储的是 f[i - 1][v] ,此时f[v-weight[i]]存储的是f[i - 1][v-weight[i]]。

    相反,如果在执行第 i 次循环时,背包容量按照0..V的顺序遍历一遍,来检测第 i 件物品是否能放。此时在执行第i次循环 且 背包容量为v时,此时的f[v]存储的是 f[i - 1][v] ,但是,此时f[v-weight[i]]存储的是f[i][v-weight[i]]。

    因为,v  > v - weight[i],第i次循环中,执行背包容量为v时,容量为v - weight[i]的背包已经计算过,即f[v - weight[i]]中存储的是f[i][v - weight[i]]。即,对于01背包,按照增序枚举背包容量是不对的。

     http://blog.csdn.net/lyhvoyage/article/details/8545852

    /*
    // 0-1背包二维数组模板
    #include <stdio.h>
    #include <stdlib.h>
    int N;     //物品的件数
    int V;     //物品的容量
    int f[500][500]; // f[i][v] 表明将第i件物品放入v容量的背包中所能获得的最大价值
    int w[500];      // w[]   物品的价值
    int c[500];      // c[]    物品的花费
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    void Knapsack()
    {
        int i,j;
        memset(f,0,sizeof(f));   // 初始化数组
        for(i = 1;i<=N;i++)
        {
            for(j = 1;j<=V;j++)
            {
                f[i][j] = f[i-1][j];
                if(j>=c[i])      // 当背包的容量大于等于当前物品的容量时就可以更新
                {
                   f[i][j] = max(f[i-1][j],f[i-1][j - c[i]] + w[i]);    // 状态转移方程(关键)
                }
            }
        }
    }
    int main()
    {
        int i;
        while(scanf("%d%d",&N,&V)!=EOF)
        {
            for(i = 1;i<=N;i++)
            {
                scanf("%d",&w[i]);
            }
            for(i = 1;i<=N;i++)
            {
                scanf("%d",&c[i]);
            }
            Knapsack();
            printf("%d
    ",f[N][V]);
        }
        return 0;
    }
    */
    // 优化空间复杂度 --- 转化为-维,用逆序
    // 逆序时 外层循环i表示物品的数目,内层循环 for(j = V;j>c[i];j--)
    #include <stdio.h>
    #include <string.h>
    
    int f[500];
    int c[500];
    int w[500];
    int N,V;
    int max(int a ,int b)
    {
        return a>b?a:b;
    }
    void Knapsack()
    {
        int i,j;
        memset(f,0,sizeof(f));
        for(i = 1;i<=N;i++)
        {
            for(j = V;j>=c[i];j--)       //关键 ,关键!!!
            {
                f[j] = max(f[j - c[i]] + w[i],f[j]);  // 状态转移方程
            }
        }
    }
    int main()
    {
        int i;
        while(scanf("%d%d",&N,&V)!=EOF)
        {
            for(i = 1;i<=N;i++)
            {
                scanf("%d",&w[i]);
            }
            for(i = 1;i<=N;i++)
            {
                scanf("%d",&c[i]);
            }
            Knapsack();
            printf("%d
    ",f[V]);
        }
        return 0;
    }
  • 相关阅读:
    如何开启无线网卡
    E-SATA接口
    sata express接口
    联想服务器驱动
    国家信息安全漏洞共享平台
    SQL SERVER 性能调优
    计算机网络知识库
    CCNP 视频
    ORACLE 培训 -相克军
    phxsql
  • 原文地址:https://www.cnblogs.com/yangyongqian/p/3942280.html
Copyright © 2011-2022 走看看