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


      现有n件物品和一个容量为c的背包。第i件物品的重量是重量为w[i],价值是v[i]。已知对于一件物品必须选择取(用1表示)或者不取(用0表示),且每件物品只能被取一次(这就是“0-1”的含义)。求放置哪些物品进背包,可使这些物品的重量总和不超过背包容量,且价值总和最大。

     01背包问题:

      c[i][j] = Max(c[i - 1][j], c[i - 1][j - weight[i]] + value[i]);

      递归公式表示 当前的最优解 = Max(不放入当前的的物品,即c[i - 1][j]    ,      放入当前物品,则要预留出这个物品的 位置 即   c[i - 1][j - weight[i]] + value[i]  )

      然后递归得到所有的解。

      每个物品只考虑放不放入一个,完全背包问题就考虑1~max个,多重就是考虑指定数量的物品,具体见代码。

      

    // Study.cpp: 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    #include <unordered_map>
    #include <unordered_set>
    #include <queue>
    #include <string>
    #include <algorithm>
    #include <sstream>
    #include <set>
    #include <stack>
    #define INT_MAX 2147483647 // maximum (signed) int value
    #define INT_MIN (-2147483647 - 1) // minimum (signed) int value
    ;
    
    
    using namespace std;
    
    int Max(int a, int b)
    {
    	return a > b ? a : b;
    }
    
    void baggage(int m, int n, vector<int> &weight, vector<int> &value)
    {
    	vector<vector<int>> c(n + 1, vector<int>(m + 1, 0));
    
    	vector<int> t(m + 1, 0);
    	//01背包问题
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = m; j >= 1; j--)
    		{
    			if (weight[i] <= j)
    			{
    				c[i][j] = Max(c[i - 1][j], c[i - 1][j - weight[i]] + value[i]);
    			}
    			else
    				c[i][j] = c[i - 1][j];
    		}
    	}
    
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= m; j++)
    		{
    			cout << c[i][j] << " ";
    		}
    		cout << endl;
    	}
    	//*******************************完全背包问题*************
    	cout << endl << "完全背包 " << endl;
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = m; j >= 1; j--)
    		{
    			for (int k = 1; k <= j / weight[i]; k++)
    				c[i][j] = Max(c[i - 1][j], c[i - 1][j - k * weight[i]] + k * value[i]);
    		}
    	}
    
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= m; j++)
    		{
    			cout << c[i][j] << " ";
    		}
    		cout << endl;
    	}
    
    	//*********多重背包问题***********
    	vector<int> num = { 0,1,1,1 };
    	cout << endl << "多重背包 " << endl;
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = m; j >= 1; j--)
    		{
    			for (int k = 1; k <= j / weight[i] && k <= num[i]; k++)
    				c[i][j] = Max(c[i - 1][j], c[i - 1][j - k * weight[i]] + k * value[i]);
    		}
    	}
    
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= m; j++)
    		{
    			cout << c[i][j] << " ";
    		}
    		cout << endl;
    	}
    
    	/*
    	//用一位数组节省空间
    
    	for (int i = 1; i <= n; i++)
    	{
    	for (int j = m; j >= 1; j--)
    	{
    	if (weight[i] <= j)
    	{
    	t[j] = Max(t[j], t[j - weight[i]] + value[i]);
    	}
    	else
    	t[j] = t[j];
    	}
    	}
    
    
    	for (int j = 1; j <= m; j++)
    	{
    	cout << t[j] << " ";
    	}
    	cout << endl;
    	*/
    
    }
    
    int main()
    {
    	int M, N;
    	//cin >> M >> N;
    
    	//vector<int> weight(N+1, 0);
    	//vector<int> value(N+1, 0);
    	//for (int i = 1; i <= N; i++)
    	//{
    	//	cin >> weight[i] >> value[i];
    	//}
    
    	M = 10, N = 3;
    	vector<int> weight = { 0,3,4,5 };
    	vector<int> value = { 0,4,5,6 };
    
    	baggage(M, N, weight, value);
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    高仿IOS下拉刷新的粘虫效果
    CSDN无耻,亿赛通无耻
    2014年10月Android面试总结
    HttpClient和HttpURLConnection的使用和区别(下)
    HttpClient和HttpURLConnection的使用和区别(上)
    Gson简单使用
    Android PowerImageView实现,可以播放动画的强大ImageView
    Android访问网络,使用HttpURLConnection还是HttpClient?
    自定义android ProgressDialog
    NPOI导Excel样式设置
  • 原文地址:https://www.cnblogs.com/Oscar67/p/9397323.html
Copyright © 2011-2022 走看看