首页 > 其他分享 >C语言wyh的物品

C语言wyh的物品

时间:2024-03-18 21:00:27浏览次数:15  
标签:int double mid C语言 left 物品 价值 wyh

题目描述

wyh学长现在手里有 n 个物品,这 n 个物品的重量和价值都告诉你,然后现在让你从中选取 k 个,问你在所有可能选取的方案中,最大的单位价值为多少(单位价值为选取的 k个物品的总价值和总重量的比值)

输入描述:

输入第一行一个整数 T(1≤T≤10)
接下来有 T组测试数据,对于每组测试数据,第一行输入两个数 n 和 k(1≤k≤n≤100000)
接下来有 n 行,每行两个是 a 和 b (0<a,b≤1000000)代表这个物品的重量和价值

输出描述:

对于每组测试数据,输出对应答案,结果保留两位小数

输入

1
3 2
2 2
5 3
2 1

输出

0.75

说明

对于样例来说,我们选择第一个物品和第三个物品,达到最优目的

 解题思路

题目中说单位价值为选取的 k个物品的总价值和总重量的比值,假设已经选定了k个物品,那么在这k个物品作用下,一个物品的价值x = 这个物品的价值 - 单位价值 * 重量,此时将所有的x累加起来就会有三种情况。

用零来分割,记求和之后的价值为X,如果X>0时,说明了单位价值取小了,需要找大;如果X<0时,说明单位价值取大了,需要找小;如果X=0,说明单位价值刚刚好;

这样来看就可以用二分来解决这个问题了,首先用数组x记入所有的差值,然后再对数组进行排序,这里的排序是降序,因为我们要找最大的单位价值,当X>0时,是需要找大的,所以需要降序;降序之后就可以求和了,求和的话只需要求题目前k项就可以了。

下面是ac代码


int cmp(const void* p1, const void* p2)
{
    return *(double*)p1 > *(double*)p2 ? -1 : 1;
}
int fun(double mid, int n, int k, double* x, int* v, int* w)
{
    double X = 0;
    for (int i = 0; i < n; i++)
    {
        x[i] = v[i] - mid * w[i];
    }
    qsort(x, n, sizeof(double), cmp);//降序排序
    for (int i = 0; i < k; i++)
    {
        X += x[i];//累加的结果
    }
    if (X >= 0)
        return 1;//大于零,mid小了,需要找大,把零归到这里(零去哪里都无所谓),因为是去用左右区间去逼近的,所以零在哪里都可以
    else
        return -1;//小于零,mid大了,需要找小

}

int main()
{

    int t;//需要输入几组测试用例
    scanf("%d", &t);
    while (t--)
    {
        int n, k;
        scanf("%d %d", &n, &k);//n是几个物品,k是选几个物品
        double x[1000000] = { 0 };//单位价值作用下的价值
        int v[1000000] = { 0 }, w[1000000] = { 0 };//v是物品的价值,w是物品的重量
        for (int i = 0; i < n; i++)
            scanf("%d %d", &w[i], &v[i]);
        double left = 0, right = 1000000;
        while (right - left > 0.000001)
        {
            double mid = (left + right) / 2.0;
            if (fun(mid, n, k, x, v, w) == 1)
                left = mid;//mid小了,找大,就让左区间直接跑到中间
            else
                right = mid;//mid大了,找小,让右区间跑到中间
        }
        printf("%.2f\n", left);
    }
    return 0;
}

标签:int,double,mid,C语言,left,物品,价值,wyh
From: https://blog.csdn.net/whitepcr/article/details/136820872

相关文章

  • C语言数据结构链表(无头结点)功能实现(增,删,改,查)
    #include<stdio.h>#include<stdlib.h>typedefstructLNode{   int data;   struct   LNode*next;}LNode,*LinkList; boolInitList(LinkList&L){    L=NULL;    return0; }boolinsert(LinkList&L,inti,intx){       ......
  • 深入C语言指针,使代码更加灵活(三)
    一、函数指针1.1函数的地址在讲解函数指针变量之前,我们先思考一下什么是函数指针变量,我们可以同数组指针变量进行类比:数组指针—是指针—是存放指向数组的指针,是存放数组地址的指针;函数指针—是指针—是存放指向函数的指针,是存放函数地址的指针;数组是有地址的,那么函数......
  • 用C语言实现二分查找
    //二分查找,前提必须是有序#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>intmain(){ intarr[]={1,2,3,4,5,6,7,8,9,10}; intsz=sizeof(arr)/sizeof(arr[0]);//求数组长度 intk=7;//要查找的数 intleft=0; intright=sz-1; intmid=0; i......
  • 学习笔记——C语言基本概念&运算符——(2)
    目录一、运算符1.1赋值运算符1.2算数运算符 1.3关系运算符1.5位运算符1.6 自增自减运算符1.7  复合运算符1.8逗号运算符1.9 三目运算符1.10 sizeof运算符附录:运算符优先性表一、运算符1>.按照操作数目分类:单目运算符,双目运算符,三目运算符。2>......
  • C语言随记————简单算法
    1.问题:如何在C语言中实现一个简单的线性查找算法? 答案:线性查找算法可以通过遍历数组的每个元素,逐一比较来查找目标值。以下是一个简单的实现示例:intlinearSearch(intarr[],intn,intx){for(inti=0;i<n;i++){if(arr[i]==x)re......
  • C语言动态链表练习(简单易懂)
    学习目标:初步认识动态链表,并会最基础的应用。题目内容:写个程序,输入a,b,c如果a>b,a=a➖b    b>c,b=b➖c    c>a,c=c➖a要求:开始时输入k➕1行数,第一行为k,代表数的组数,下面每一行为一个组,每组四个数,前三个为a,b,c,最后一个为这组数进行上述计算的次数题目特点分析:开始......
  • 使用vscode编辑c语言
    在VisualStudioCode(VSCode)中配置C语言环境步骤指南:一,前期准备(安装扩展,软件包)安装C/C++扩展打开VSCode。点击左侧边栏的扩展按钮(或使用快捷键Ctrl+Shift+X)。在搜索框中输入C/C++。从结果中找到Microsoft的C/C++扩展并点击“安装”。安装MinGW或......
  • C语言指针完整总结!!!
    1.指针介绍1.简介:C语⾔中给地址起了新的名字叫:指针。一个内存单元是一字节内存单元的编号==地址==指针在x86的环境中,一共有32根地址总线,即32个比特位。一个字节有八个比特位,而⼀个比特位可以存储⼀个2进制的位1或者0,因此32根地址线,就能表示2^32种含义,每⼀种含义都......
  • #c语言程序设计————实验报告
    实验项目名称:实验一熟悉C语言运行环境实验项目类型:验证性实验日期:2023年3月14日一、实验目的下载安装Devc6.0程序。了解在该系统上如何进行编辑、编译、连接和运行一个C程序。通过运行简单的C程序了解C程序的特点。二、实验硬、软件环境Windows计算机、Devc6.0三、......
  • C语言自定义类型:枚举(C语言进阶)
    目录前言1、枚举类型定义2、枚举的优点3、枚举的使用结语前言    本篇文章讲解C语言自定义类型:枚举类型。    枚举顾名思义就是一一列举,把可能的值一一列举。像一周的周一到周日可以枚举;每年12个月,可以枚举。1、枚举类型定义enumDay//星期{ Mo......