51nod 1257 背包问题 V3(这不是背包问题是二分)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1257

题解:不能按照单位价值贪心,不然连样例都过不了

要求的r=sum(x[i]*p[i])/sum(x[i]*w[i])不妨设一个辅助函数

z(l)=sum(x[i]*p[i])-l*sum(x[i]*w[i]),

如果z(l) > 0 即sum(x[i]*p[i])-l*sum(x[i]*w[i])>0-->sum(x[i]*p[i])/sum(x[i]*w[i])>l也就是说存在

比当前更大的l值也就是所要求的最大值r,于是二分一下答案就行了。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int M = 5e4 + 10;
struct TnT {
    int w , p;
    double r;
}T[M];
int n , k;
ll fz , fm;
bool cmp(TnT x , TnT y) {
    return x.r > y.r;
}
ll gcd(ll a , ll b) {
    return (b > 0) ? gcd(b , a % b) : a;
}
bool check(double l) {
    for(int i = 0 ; i < n ; i++) {
        T[i].r = 1.0 * T[i].p - 1.0 * T[i].w * l;
    }
    sort(T , T + n , cmp);
    double sum = 0.0;
    fz = 0 , fm = 0;
    for(int i = 0 ; i < k ; i++) {
        fz += T[i].p;
        fm += T[i].w;
        sum += T[i].r;
    }
    if(sum >= 0) return true;
    return false;
}
int main() {
    cin >> n >> k;
    for(int i = 0 ; i < n ; i++) {
        cin >> T[i].w >> T[i].p;
    }
    double l = 0.0 , r = 50000.0;
    ll up , down;
    for(int i = 0 ; i <= 50 ; i++) {
        double mid = (l + r) / 2;
        if(check(mid)) {
            l = mid;
            up = fz , down = fm;
        }
        else r = mid;
    }
    ll gg = gcd(up , down);
    cout << up / gg << ‘/‘ << down / gg << endl;
    return 0;
}
时间: 2024-08-18 21:26:37

51nod 1257 背包问题 V3(这不是背包问题是二分)的相关文章

51nod 1257 01分数规划/二分

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1257 1257 背包问题 V3 基准时间限制:3 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 N个物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数),从中选出K件物品(K <= N),使得单位体积的价值最大. Input 第1行:包括2个数N, K(1 <= K <=

背包问题:0/1背包问题 普通背包问题(贪心算法只适用于普通背包问题)

//sj和vj分别为第j项物品的体积和价值,W是总体积限制. //V[i,j]表示从前i项{u1,u2,…,un}中取出来的装入体积为j的背包的物品的最大价值. 第一种:0/1背包问题 最大化 ,受限于  1)若i=0或j=0,  V[i,j] = 0 2)若j<si, V[i,j] = V[i-1,j] 3)若i>0且j>=si, V[i,j] = Max{V[i-1,j],V[i-1,j-si]+vi} 第二种:背包问题:在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部

【51nod】 第K大区间2(二分+树状数组)

[51nod] 第K大区间2(二分+树状数组) 第K大区间2 ﹡    LH (命题人) 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 定义一个长度为奇数的区间的值为其所包含的的元素的中位数.中位数_百度百科 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 [3]:2 [4]:4 [1,3]:2 [2,4]:2 第三大是2 Input 第一行两个数n和k(1<=n<=100000,k&l

51nod 1257 背包问题 V3(分数规划)

显然是分数规划...主要是不会求分数的形式,看了题解发现自己好傻逼QAQ 还是二分L值算出d[]降序选K个,顺便记录选择时候的p之和与w之和就可以输出分数形式了... #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #incl

1257 背包问题&#160;V3——分数规划

N个物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数),从中选出K件物品(K <= N),使得单位体积的价值最大. Input 第1行:包括2个数N, K(1 <= K <= N <= 50000) 第2 - N + 1行:每行2个数Wi, Pi(1 <= Wi, Pi <= 50000) Output 输出单位体积的价值(用约分后的分数表示). Input示例 3 2 2 2 5 3 2 1 Output示

51nod 1090 3个数和为0(排序+二分)

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1090 首先将序列进行排序,然后根据a+b+c=0,c=-a-b,二分查找c,注意判重,即c>b. 时间复杂度O(n*n*logn). #include<bits/stdc++.h> using namespace std; int n,a[1005]; int find(int x) { int l=0,r=n-1; while(l<=r) { int

[51nod] 1267 4个数和为0 暴力+二分

给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No". Input 第1行,1个数N,N为数组的长度(4 <= N <= 1000) 第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9) Output 如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No". Input示例 5 -1 1 -5 2 4 Output

51nod 1090 3个数和为0【二分】

1090 3个数和为0 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等.从中找出所有和 = 0的3个数的组合.如果没有这样的组合,输出No Solution.如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则按照第二小的数排序. Input 第1行,1个数N,N为数组的长度(0 <= N <= 1000) 第2 - N + 1行:A[i](-10^9 &l

背包问题-01背包

*/--> 背包问题-01背包 Table of Contents 1 问题描述 2 问题思路 2.1 问题定义 2.2 实例演讲 3 问题思考 3.1 优化-定义问题 3.1.1 索引的改变 3.1.2 顺序的改变 3.2 优化-复杂度 3.3 初始值的思考 4 问题延伸 4.1 01背包问题的其他解法 4.2 01背包问题的实际引用 5 参考阅读 1 问题描述 背包问题主要分为三种:01背包 完全背包 多重背包. 01背包就是本文要讨论的问题. 有N件物品和一个容量为W的背包,每种物品 均只