zoukankan      html  css  js  c++  java
  • 题解 CF507A Amr and Music

    建议更改题目难度为:普及-

    题意:

    (n) 个物品,装进容量为 (k) 的背包(可以不装满),装进的物品数目要尽量多,输出装进物品的数量并输出它们的编号。

    编号顺序任意排列,使用 Special Judge

    解析:

    这道题乍一看好像是01背包,但由于有了因为价值都为1、可以不装满的条件背包,所以每步的选择没有后效性且局部最优解的总和可以推出全局最优解,于是就可以使用贪心算法来解决。

    大概步骤:

    1. 读入数据并将数据依物品的重量排序为单调递增形式。

    2. 判断背包剩余容量与背包外最小物品重量的大小,若背包剩余容量 (geqslant) 背包外最小物品重量,则将此物品装入背包并更新背包剩余容量。重复执行此步骤直至背包剩余容量 (<) 背包外最小物品重量,此时解为最优。

    3. 输出背包内物品数量并按任意顺序输出背包内各物品编号。

    实现:

    因为需要输出物品编号,所以难以使用一维整形数组来进行数据存储与排序。我运用了结构体类型 priority_queue (优先队列)来进行数据存储与排序,利用运算符重载来进行自定义排序。

    但是,这道题输出要求先输出背包内物品的数量,就导致我们无法边判断边输出浪费了大把时间,于是我使用了 stack 容器来存储各物品编号,在判断完成后再进行输出。

    代码:

    (437ms,8KB)

    #include<bits/stdc++.h>
    using namespace std;
    struct NODE{
    	int w,num;
    	bool operator <(const NODE&v)const{
    		return w>v.w;
            //运算符重载自定义优先队列排序为依重量降序
    	}
    };
    priority_queue<NODE>c;
    stack<int>o;
    int n,k,ans=0;
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=1,ci;i<=n;i++){
    		scanf("%d",&ci);
    		c.push({ci,i});
    	}
    	for(int i=1;i<=n;i++)
    		if(!c.empty()){
    			NODE h=c.top();
    			c.pop();
    			if(k>=h.w){
    				o.push(h.num);//存入物品编号数据
    				k-=h.w;
    			}
    			else
    				break;
    		}
    		else
    			break;
    	printf("%d
    ",o.size());
    	while(!o.empty())
    	{
    		printf("%d ",o.top());
    		o.pop();
    	}
    	return 0;
    }
    
  • 相关阅读:
    sklearn的train_test_split函数
    Tensorflow报错:InvalidArgumentError: You must feed a value for placeholder tensor 'input_y' with dtype
    conda install 安装太慢怎么办?
    python merge、concat合并数据集
    如何调用写好的指定模块?——sys.path
    对分类特征做编码
    ThreadPoolExecutor的创建
    MYSQL中VARCHAR长度怎么选?
    JAVA实现一个低性能的WEB服务器(一)——线程池
    在连接校园网的同时连接外网|同时访问内网与外网
  • 原文地址:https://www.cnblogs.com/Dr-Albert-Wensley/p/JUTJ-0x03.html
Copyright © 2011-2022 走看看