背包问题总结第一讲——可拆分背包

题目:

有N件物品和一个容量为V的背包。第i件物品占空间c[i],价值是w[i],物品可拆分,求解将哪些物品装入背包可使价值总和最大。

基本思路:

    因为物品可拆分,故为了使整个背包内物品的总价值最大,可按照物品单位价值,依次从大到小装入,使背包的每份空间的价值尽可能大。

类型:

    贪心算法。策略:按物品单位价值降序依次装入,直至物品剩余为0,或背包剩余空间为0。

代码:

#include <iostream>
#include <vector>
#include <algorithm>
#define MAX 100
using namespace std;
typedef struct
{
    int c,v;
    float pj;
}NODE;
bool compare(NODE a,NODE b)
{
    return a.pj>b.pj;
}


int main()
{
    vector<NODE> p;
    int bag_v;
    float result = 0.0;
    int i,j,n;
    cin>>n;                        //number of cases
    while(n--)
    {
        cin>>bag_v;                //v of the bag
        cin>>i;                    //number of things
        NODE tmp;
        for(j=1 ; j<=i ; j++)
        {
            cin>>tmp.c>>tmp.v;
            tmp.pj = (float)tmp.v/tmp.c;
            p.push_back(tmp);
        }
        sort(p.begin(),p.end(),compare);
        vector<NODE>::iterator i = p.begin();
        while(i!=p.end() && bag_v>0)
        {
            if(bag_v >= (*i).c)
            {
                result += (*i).v;
                bag_v -= (*i).c;
            }
            else
            {
                result += (*i).pj * bag_v;
                bag_v = 0;
            }
            i++;
        }
        cout<<"max value is "<<result<<endl;
    }
    return 0;
}
贪心算法的应用,也是背包中最简单的一个。

 

举例应用:

1.有开放时间区间为[s,e]的会议室,现有N个会议,分别需要用会议室的时间段为[a1,b1],[a2,b2],[a3,b3],...,[an,bn]。

  求最多可以举行多少个会议。

2.有存储空间为S的一盒磁盘,现有N个文件需要存入,文件i的大小为a[i],问最多可以存多少个文件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的代码示例,展示了Unity中如何实现背包物品的使用、分和销毁功能: ```csharp using System.Collections.Generic; using UnityEngine; public class BackpackManager : MonoBehaviour { public List<Item> backpackItems = new List<Item>(); public void UseItem(Item item) { // 执行使用物品的逻辑 // 可以根据物品的类型进行不同的处理 // 例如增加玩家的血量、攻击力等 // 从背包中移除使用的物品 backpackItems.Remove(item); } public void SplitItem(Item item, int splitAmount) { if (splitAmount >= item.amount) { Debug.Log("无法分更多物品"); return; } // 创建一个新的物品,作为分出来的部分 Item splitItem = new Item(item.id, item.name, splitAmount); // 减少原物品的数量 item.amount -= splitAmount; // 将分出来的物品添加到背包中 backpackItems.Add(splitItem); } public void DestroyItem(Item item) { // 从背包中移除销毁的物品 backpackItems.Remove(item); } } public class Item { public int id; public string name; public int amount; public Item(int id, string name, int amount) { this.id = id; this.name = name; this.amount = amount; } } ``` 在上述示例中,`BackpackManager` 脚本管理着玩家的背包物品。`backpackItems` 列表存储着玩家拥有的物品。 使用 `UseItem` 方法可执行使用物品的逻辑,并从背包中移除使用的物品。 使用 `SplitItem` 方法可分指定数量的物品。如果分数量大于等于物品当前的数量,则无法分更多物品。 使用 `DestroyItem` 方法可销毁指定的物品,将其从背包中移除。 请注意,上述示例仅为演示用途,您可能需要根据您的具体需求进行修改和扩展。例如,您可以添加更多的物品属性,实现更复杂的逻辑等。希望这个示例对您有所帮助!如有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值