首页 > 其他分享 >P1507 洛谷 理解与分析

P1507 洛谷 理解与分析

时间:2022-08-18 11:45:24浏览次数:88  
标签:01 P1507 int max 理解 物品 洛谷 背包 dp

题目大意

食品的体积就是01背包问题中的体积 也就是 w 数组

食品的所含卡路里就是01背包问题中的价值 也就是 v 数组

所以这就是一道 01背包问题模板题

题目分析

使用dp 套01背包的模板

01背包问题的模板

状态转移方程

01背包的状态转移方程为

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

i 代表对 i 件物体做决策,有两种方式:

1.放入背包

2.不放入背包。

j 表示当前背包剩余的容量。

转移方程的解释:
创建一个状态矩阵 f ,横坐标 i 是物体编号纵坐标 j 为背包容量
首先将 f 第 0 行和第 0 列初始化为 0

注意:代码里面将整个 f 初始化为 0 了,其实只初始化第 0 行和第 0 列就够了 这个表示不放物体时最大价值为 0 。物体编号从 1 开始
接下来依次遍历 f 的每一行

如下所示

for (int i = 1; i <= n; i++)
{
	for (int j = V; j >= 0; j--) //所有的背包大小
	{
		if (j >= w[i]) //如果背包装得下当前的物体
		{
			f[i][j] = max(f[i - 1][j], f[i - 1][j - w[i]] + v[i]);
		}
		else //如果背包装不下当前物体
		{
			f[i][j] = f[i - 1][j];
		}
	}
}

01背包问题正解

#include<bits/stdc++.h> 
using namespace std;
 
int dp(int n, int m, int v[], int w[])
{
	int f[1000][1000];
	for (int i = 0;i <= n;i++)
		f[i][0] = 0;
	for (int j = 0;j <= n;j++)
		f[0][j] = 0;
	for (int i = 1;i <= n;i++)
	{
		for (int j = 0;j <= m;j++)
		{
			if (j < w[i])
				f[i][j] = f[i - 1][j];
			else
			{
				f[i][j] = max(f[i - 1][j], f[i - 1][j - w[i]] + v[i]);
			}
 
		}
	}
	return f[n][m];
 
}
int main()
{
	int n, m, v[101], w[101];
	cin >> n >> m;//n为物品个数,m为背包容量,w为物品重量,v为物品价值 
	for (int i = 1;i <= n;i++)
	{
		cin >> w[i] >> v[i];
	}
 
	cout << dp(n, m, v, w);
	return 0;
}

转换到这道题的做法就是:

当这个物品能取时,也就是 j >= v [ i ]&& k >= w [ i ]时

f [ i ][ j ][ k ]= max ( f [ i-1 ][ j ][ k ], f [ i-1 ][ j-v[i] ][ k-w[i] ]);

否则

f [ i ][ j ][ k ]= f [ i-1 ][ j ][ k ];

谁抄袭啊? 逊

完整代码

#include<bits/stdc++.h> 
using namespace std;

//n为物品个数 
int n;

//背包 物品
struct node
{
    int V;
    int T;
    int KaLuLi;
};

//背包
int Vv,Ww;

//物品
node w[524];

//dp数组
int f[500][500][500];


void dp()
{


    //计算
	for(int i=1;i<=n;i++)
    {   
		for(int j=Vv;j>=0;j--)
        {
			for(int k=Ww;k>=0;k--)
            {
				if(j>=w[i].V&&k>=w[i].T)
                {
                    f[i][j][k]=max(f[i-1][j][k],f[i-1][j-w[i].V][k-w[i].T]+w[i].KaLuLi);
                }
					
				else
                {
                    f[i][j][k]=f[i-1][j][k];
                } 
			}
		}
	}
	cout<<f[n][Vv][Ww]<<endl;
 
}
int main()
{
	//体积最大值和质量最大值
    cin>>Vv>>Ww; 

    //食品总数
    cin>>n;

    //物品信息
	for(int i=1;i<=n;i++)
	{
		cin>>w[i].V>>w[i].T>>w[i].KaLuLi;
	}
 
	dp();


	return 0;
}

标签:01,P1507,int,max,理解,物品,洛谷,背包,dp
From: https://www.cnblogs.com/YzaCsp/p/16598121.html

相关文章

  • java线程安全的理解(转载)
    记录两篇关于java线程安全理解的文章https://blog.csdn.net/m0_59139260/article/details/123866585?ops_request_misc=%257B%2522request%255Fid%2522%253A%252216607914......
  • V8中的快慢属性(图文分解更易理解)
    出于好奇:js中使用json存数据查找速度快,还是使用数组存数据查找快?探究V8中对象的实现原理,熟悉数组索引属性、命名属性、对象内属性、隐藏类、描述符数组、快慢属性等等。......
  • GIS中的概念理解
    GIS中的概念理解要素、要素类​ 要素(feature):就是能代表物理实体的,具有几何形状的地图元素。地图中主要包括点,线,面三要素。是空间数据中最基本,不可分割的单位。每个......
  • 22/8/17深入理解计算机系统第七章笔记
    7.13库打桩机制库打桩:允许截获对共享库的调用,转而执行自己的代码。使用这个机制可以追踪某个特殊库函数的调用次数,验证和追踪它的输入和输出值,或者替换它。需要创建一个......
  • 【算法基础】旋转卡壳算法理解
    前言 参考1.旋转卡壳系列博客;2. 旋转卡壳(1)--求凸包(点集)直径poj2187;完......
  • 【python基础】super的理解
    super() 函数是用于调用父类(超类)的一个方法。super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序......
  • 关于read指向缓冲区的理解
    read在linux原型定义如下: #include<unistd.h>ssize_tread(intfd,void*buf,size_tcount);关于buf,man手册解释如下:“read()attemptstoreaduptocountby......
  • 洛谷 P3157 [CQOI2011]动态逆序对
    Description对于序列\(a\),它的逆序对数定义为集合\[\{(i,j)|i<j\anda_i>a_j\}\]中的元素个数。现在给出\(1\simn\)的一个排列,按照某种顺序依次删除\(m\)个......
  • 洛谷P1972HH的项链 题解
    P1972[SDOI2009]HH的项链题目描述HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含......
  • c语言<<,>>应用理解
    不讲原理,在使用中总结的规律,在进制转换中遇到10机制的左移或右移,可以将变量乘以2的n次方或者除以2的n次方,左乘,右除,但是乘除要考虑高位的数据溢出,低位数据的丢失。例如十进......