zoukankan      html  css  js  c++  java
  • P4377 [USACO18OPEN]Talent Show

    一开始他还不是题解,是草稿……

    题解

    (x_i) 表示第 (i) 个点选或不选,可得

    [ans=max(frac{ sum_{i=1}^{n}(x_i imes t_i)}{sum_{i=1}^{n}(x_i imes w_i)}) ]

    我们不妨设一个函数如下

    [y=ans imes sum_{i=1}^{n}(x_i imes w_i)-sum_{i=1}^{n}(x_i imes t_i) ]

    我们以 (ans) 为自变量,(y) 为因变量,剩下的表达式的所有取值为常量,我们就可以画出 (2^n) 方个函数图像,我们可以简单画一下函数图像(随便画的几根线)。

    首先,可以得到的是,这个 (ans) 要成立的话是要有一条函数的在取自变量为当前 (ans) 的情况下取 (0) 。(十分显然,不然就不满足我们上面的第一个式子了)

    同时我们需要 (ans) 最大,所以我们需要找到最右边的一个满足条件的 (ans) ,在本图中就是黄色直线与 (y) 轴的交点。

    然后我们考虑如何找出这个交点,可以发现,对于一个固定的 (ans) ,我们可以通过求所有函数的最小值与 (0) 的关系来求解。如果最小值小于 (0) ,那么 (ans) 偏小;如果大于 (0) ,那么 (ans) 偏大;如果等于,那么就是答案。发现这个东西是满足单调性的,可以二分求解;同时求最小值的操作是可以 (dp) 的,复杂度是满足的。

    但是这道题目还给我们添加了一个限制条件,即重量和必须大于等于 (W) ,我们可以考虑在 (dp) 的时候添加限制条件。我们设(f_{i,j}) 表示到第 (i) 个点,且重量和为 (j) 时的最小值是什么,我们可以发现 (w_i) 的值很大,但是 (W) 的值很小,所以我们只需要维护 (1000) 就可以了,大于 (1000) 的都放在一千。

    以上。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=255,W=1005;
    int n,w;
    struct Cow{int w,t;}s[N];
    double f[W];
    double l,r,mid,ans;
    bool check(double now)
    {
    	f[0]=0;
    	for(int i=1;i<=w;++i) f[i]=1e9+7;
    	for(int i=1;i<=n;++i)
    	{
    		for(int j=w;j>=0;--j)
    		f[min(j+s[i].w,w)]=min(f[min(j+s[i].w,w)],f[j]+now*s[i].w-s[i].t);
    	}
    	return f[w]<=0;
    }
    int main()
    {
    	cin>>n>>w;
    	for(int i=1;i<=n;++i) scanf("%d%d",&s[i].w,&s[i].t);
    	l=0,r=250000;
    	while(r-l>1e-4)
    	{
    		// printf("%lf %lf
    ",l,r);
    		mid=(l+r)/2;
    		if(check(mid))
    		l=ans=mid;
    		else r=mid;
    	}
    	printf("%d
    ",(int)(ans*1000));
    }
    
  • 相关阅读:
    项目常见异常
    mysql 存储过程中使用事物+事件定时执行存储过程
    Spring Mvc 配置 之 ContextLoaderListener
    Spring Boot 之 https
    Spring Boot 之 annotation注解
    用python打印99乘法口诀表
    gerrit代码审核工具之“error unpack failed error Missing unknown”错误解决思路
    在eclipse搭建python开发环境
    python2与python3语法区别之_重定向
    2_jenkins_git创建创建及项目构建
  • 原文地址:https://www.cnblogs.com/Point-King/p/13652170.html
Copyright © 2011-2022 走看看