POJ3111 K Best(另类背包+二分+变态精度)

POJ3111 K Best,看讨论区说数据有点变态,精度要求较高,我就直接把循环写成了100次,6100ms过,(试了一下30,40都会wa,50是4000ms)

  第一次在POJ上看到下面这种东西还是很好奇的,

  一个题目可以接受多种正确答案,即有多组解的时候,题目就必须被Special Judge.
Special Judge程序使用输入数据和一些其他信息来判答你程序的输出,并将判答结果返回.

Case Time Limit: 2000MS   Special Judge

  

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define in(n) scanf("%d",&(n))
#define in2(x1,x2) scanf("%d%d",&(x1),&(x2))
#define inll(n) scanf("%I64d",&(n))
#define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2))
#define inlld(n) scanf("%lld",&(n))
#define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2))
#define inf(n) scanf("%f",&(n))
#define inf2(x1,x2) scanf("%f%f",&(x1),&(x2))
#define inlf(n) scanf("%lf",&(n))
#define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2))
#define inc(str) scanf("%c",&(str))
#define ins(str) scanf("%s",(str))
#define out(x) printf("%d\n",(x))
#define out2(x1,x2) printf("%d %d\n",(x1),(x2))
#define outf(x) printf("%f\n",(x))
#define outlf(x) printf("%lf\n",(x))
#define outlf2(x1,x2) printf("%lf %lf\n",(x1),(x2));
#define outll(x) printf("%I64d\n",(x))
#define outlld(x) printf("%lld\n",(x))
#define outc(str) printf("%c\n",(str))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define mem(X,Y) memset(X,Y,sizeof(X));
typedef vector<int> vec;
typedef long long ll;
typedef pair<int,int> P;
const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
const double INF=0x3f3f3f3f;
const ll mod=1e9+7;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const bool AC=true;

int n,k;
struct point{
    double w,v,c;
    int num; //保存编号,便于输出答案
};
point p[100005];
bool cmp(point x,point y){
    return x.c>y.c;
}
bool C(double x){
    double sum=0;
    rep(i,0,n){
        p[i].c=p[i].v-p[i].w*x;
    }
    sort(p,p+n,cmp);
    rep(i,0,k){
        sum+=p[i].c;
    }
    return sum>=0;
}
int main(){
    in2(n,k);
    rep(i,0,n){
        inlf2(p[i].v,p[i].w);
        p[i].num=i;
    }
    double lb=0,ub=INF;

    rep(i,0,100){
        double mid=(lb+ub)/2;
        if(C(mid)) lb=mid;
        else ub=mid;
    }
    rep(i,0,k){
        printf("%d\n",p[i].num+1);编号加一
    }
    return 0;
}
时间: 2024-10-25 22:21:00

POJ3111 K Best(另类背包+二分+变态精度)的相关文章

11.05T5 另类背包

[问题描述] 给定n个物品,每个物品可以不选或选一个,第i个物品的价格为ci,价值为vi,出现时间为ti.有m个询问,每次询问在出现时间不超过Ti的所有物品中选若干件,总花费不超过Mi的情况下,被选择物品的价值和的最大值是多少. [输入格式] 第一行输入n,m. 接下来n行每行3个整数表示ci,vi,ti. 接下来m行询问每行2个整数表示ti,mi. [输出格式] 输出m行,每行一个整数表示第i个询问的答案. [样例输入] 5 2 3 6 1 5 7 4 8 2 9 10 1 7 3 3 4 9

HDU2639 第k小01背包 xingxing在努力

这个题目是求解第k小01背包, 我们只需要再多加一维表示容量为j时的价值即可..代码里面用了归并排序的思想来求解f[j][k], 代码如下: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int f[1000+10][35]; int A[35], B[35]; //A选 B不选 int W[100+10], V[100+10]; int N, v, K; v

poj 3111 K Best 最大化平均值 二分思想

poj 3111 K Best 最大化平均值 二分思想 题目链接: http://poj.org/problem?id=3111 思路: 挑战程序竞赛书上讲的很好,下面的解释也基本来源于此书 设定条件C(x):=可以选择使得单位重量的价值不小于x 如何判定C(x)是否可行 假设选了某个物品的集合是S,那么单位重量的价值是:\[ \sum\limits_{i \in S} {v_i } /\sum\limits_{i \in S} {w_i } \] 因此就变成了判断是否存在S满足下面的条件:\[

第K大01背包

其实这个问题,真的挺好想的,但是我咋想了那么久呢~~ 很好理解,第K大01背包一定基于01背包,dp数组也很容易的想到由dp[V]  ---->   dp[V][K],来表示背包容量是V时候的第K大背包 然后就是状态转移方程了,多写一写,你也能手推出来的,不能被吓到 dp[V][1] = max_第一大(dp[v][1],dp[v-w][1]+vi) dp[V][2] = max_第二大数(dp[v][1],dp[v-w][1]+vi,dp[v][2],dp[v-w][2]+vi) =  max

[POJ3111]K Best(分数规划, 二分)

题目链接:http://poj.org/problem?id=3111 求选k对数,使得上述式子值最大.容易想到设左边为一个值,对式子变形以下,得到sigma(v-r*w))==0的时候就是最大的,<0是最小的.二分这个r就行了. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits>

HDU 1007 Quoit Design(二分+浮点数精度控制)

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 47104    Accepted Submission(s): 12318 Problem Description Have you ever played quoit in a playground? Quoit is a game in which fla

POJ 1064 Cable master(二分查找+精度)(神坑题)

POJ 1064 Cable master 一开始把 int C(double x) 里面写成了  int C(int x) ,莫名奇妙竟然过了样例,交了以后直接就wa. 后来发现又把二分查找的判断条件写错了,wa了n次,当 c(mid)<=k时,令ub=mid,这个判断是错的,因为要找到最大切割长度,当满足这个条件时,可能已经不是最大长度了,此时还继续缩小区间,自然就wa了,(从大到小递减,第一次满足这个条件的值,就是最大的值),正确的判断是当 c(mid)<k时,令ub=mid,这样循环1

poj3122--Pie(二分的精度问题)

Pie Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11178   Accepted: 3899   Special Judge Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of

BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N,M<=50000,N,M<=50000a<=b<=N1操作中abs(c)<=N2操作中c<=Maxlongint 之前用树套树抄过一次...然而我并不适合写那玩意儿... 加上时间序的整体二分 普通的整体二分先处理了所有$[l,mid]$的影响因子在计算询问的答案来分组