背包问题笔记(参考用)(板子?)

博客涉及C++、C语言和C#相关信息技术内容,但具体内容未给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*0-1背包:只许选择一次 
问题:有N个物品和一个容量为S的背包,第i件物品的重量是w[i],价值是v[i]。在每种物品只许放一次,不可拆分,不超过背包容量的前提下,问如何才能让背包的总价值最大。
f[i][j]=f[i-1][j-w[i]]+v[i]和f[i-1][j]的较大项*/
#include<iostream>
#include<algorithm>
using namespace std;
struct thing{
	int v,p;
}want[30]; 
long long c[10010],d[10010];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>want[i].v>>want[i].p;
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=n;j>=want[i].v;j--)
		{
			c[j]=max(c[j],c[j-want[i].v]+want[i].v*want[i].p);
		}
	}
	cout<<c[n]<<endl;
	return 0;
}
/*完全背包:物品数量选择无限制
问题:
有N个物品和一个容量为S的背包,第i件物品的重量是w[i],价值是v[i]。在每种物品有无限个,不可拆分,不超过背包容量的前提下,问如何才能让背包的总价值最大。*/
#include<iostream>
#include<algorithm>
using namespace std;
struct thing{
	int v,p;
}want[30];
long long c[10010];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>want[i].v>>want[i].p;
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=want[i].v;j<=n;j++){
			c[j]=max(c[j],c[j-want[i].v]+want[i].p);
		}
	} 
	cout<<c[n]<<endl;
	return 0;
}
/*多重背包:物品数量有上限 
有N个物品和一个容量为S的背包,第i件物品的重量是w[i],价值是v[i],上限是c[i]。在不可拆分,不超过背包容量的前提下,问如何才能让背包的总价值最大。*/
#include<iostream>
#include<algorithm>
using namespace std;
struct thing { 
  int v,p,s;
} want[30];
long long c[10010];
int main() 
{ 
  	int n,m;       
  	cin>>n>>m;      
  	for(int i=1; i<=m; i++) 
  	{
  		cin>>want[i].v>>want[i].p>>want[i].s;        
  	}        
  	for(int i=1; i<=n; i++) 
	{ 
     	for(int j=m;j>=want[i].v; j--) 
		{
         	for(int k=0;k<=want[i].s; k++)
			 {
              	if(j >=k*want[i].v)
              	{
              		c[j]=max(c[j],c[j-k*want[i].v]+k*want[i].p); 
				}
        	}          
     	}       
  	}          
  	cout << c[m] << endl;      
  	return 0;
}
/*混合背包
有N个物品和一个容量为S的背包,第i件物品的重量是w[i],价值是v[i],上限是c[i](若为0则可取无限个)。在不可拆分,不超过背包容量的前提下,问如何才能让背包的总价值最大。*/
#include<iostream>
#include<algorithm>
using namespace std;
struct thing{
	int v,p,s;
}want[30];
long long c[10010];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>want[i].v>>want[i].p>>want[i].s;
	}
	for(int i=1;i<=m;i++){
		if(want[i].s==0){//完全背包
			for(int j=want[i].v;j<=m;j++)
			{
				f[j]=max(f[j],f[j-w[i]+v[i]]);
			} 
		}
		else
		{
			for(int j=m;j>=want[i].v;j--){//0-1和多重背包
				for(int k=0;k<=want[i].s;k++){
					if(j>=k*want[i].v)
					{
						c[j]=max(c[j],c[j-k*want[i].v]+k*want[i].p);
					}
				} 
			}
		}
	}
	cout<<c[m]<<endl;
	return 0;
}
//0-1背包最优解 
#include<iostream>
#include<algorithm>
using namespace std;
int n,s,f[100],w,v;
int main()
{
	cin>>n>>s;
	for(int i=1;i<=n;i++)
	{
		cin>>w>>v;
		for(int j=s;j>=w[i];j--)
		{
			f[j]=max(f[j],f[j-w]+v);
		}
	}
	cout<<f[s]<<endl;
	return 0;
}
在C语言中实现背包问题的贪心算法通常涉及到0-1背包问题,其中我们试图选择一组物品放入背包,以便总价值最大,但每个物品只能取一次。贪心策略通常是按照每件物品单位价值(即单个物品的价值除以其重量)从高到低排序。 以下是简单的贪心算法步骤: 1. 初始化:将所有物品按单位价值降序排列。 2. 遍历物品:对于每个物品,检查它是否能完全装入当前背包容量,如果可以,则添加该物品,并更新背包剩余容量;如果不可以,只添加那些刚好填满剩余容量的部分,因为这样可以获得最大的单位价值。 3. 重复步骤2,直到背包无法再容纳更多的物品。 这里是一个简化的伪代码示例: ```c #include <stdio.h> typedef struct { int weight; int value; } Item; void greedy Backpack(int capacity, Item items[], int n) { for (int i = 0; i < n; i++) { if (items[i].weight <= capacity) { // 如果物品能全部装下 capacity -= items[i].weight; total_value += items[i].value; } else { // 否则,尽可能多地装入价值最高的部分 int take = capacity / items[i].weight; total_value += take * items[i].value; capacity %= items[i].weight; } } } int main() { // 实例化背包和物品数组... return 0; } ``` 请注意,贪心算法并不保证一定能得到最优解,对于一些特殊情况如完全背包问题,可能存在其他更好的解决方案。因此,在实际应用中,需要验证贪心策略的结果是否满足问题的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【执珪】瑕瑜·夕环玦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值