zoukankan      html  css  js  c++  java
  • CQOI2012 模拟工厂

    Description

    一个工厂每一时刻可以提高 \(1\) 生产力或者生产商品, \(n\) 个订单给出时间,数量,收益,问最大收益。

    \(1\leqslant n\leqslant15\)

    Solution

    首先 \(2^n\) 枚举选哪个订单,然后判断是否可行。

    从第一个订单开始,状态可以用剩余存量 \(rem\) 和生产力 \(pro\) 表示,如果当前是第 \(i\) 个订单, \(i-1\)\(i\) 之间时间为 \(t\) ,那么枚举 \(j\)\(i\)\(n\) ,对于 \(i\)\(j\) 这一段都应该是满足总量的,对于 \(j\) ,因为 \(i\sim j-1\) 是已经满足了的,所以我们可以看成这些量都在 \(j\) 的时刻,这样也不会影响对于总量是否合法的判断,这些量总量为 \(sum\) ,若加生产力所需时间为 \(x\) ,那么有 \((t-x)\times (pro+x)+rem\geqslant sum\)\(x^2+x\times(p-t)+s-r-t\times p\leqslant0\),可以解得 \(x\) 的区间为 \([l_j,r_j]\) ,这时总量满足了,但无法判断之后生产的速度能否满足,因此要让 \(pro\) 尽可能大,选最大的 \(\lfloor r_j\rfloor\) 中的最小值即可。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    #define MAXN 20
    #define LL long long
    #define INF 0x3f3f3f3f3f3f3f3f
    struct query
    {
    	LL t,g,m;
    }q[MAXN];
    bool cmp(query a,query b){return a.t < b.t;}
    bool sel[MAXN];
    int s[MAXN],tot; 
    long long ans = 0;
    LL calc(LL t,LL pro,LL rem,LL sum)//x^2+x*(p-t)+s-r-t*p<=0 
    {
    	LL a = 1,b = pro - t,c = sum - rem - t * pro;
    	LL delta = b * b - 4 * a * c;
    	if(delta < 0)return -1;
    	return (-b + sqrt((double)delta)) / 2;
    }
    void solve()
    {
    	tot = 0;
    	for(int i = 1;i <= n;++i)if(sel[i])s[++tot] = i;
    	LL pro = 1,rem = 0;
    	for(int i = 1;i <= tot;++i)
    	{
    		LL sum = 0,t = q[s[i]].t - q[s[i - 1]].t;
    		LL x = INF;
    		for(int j = i;j <= tot;++j)
    		{
    			sum = sum + q[s[j]].g;
    			x = min(x,calc(q[s[j]].t - q[s[i - 1]].t,pro,rem,sum));
    		}
    		if(x < 0)return;
    		pro += x;
    		rem = rem + (t - x) * pro - q[s[i]].g;
    	}
    	LL res = 0;
    	for(int i = 1;i <= tot;++i)res += q[s[i]].m;
    	ans = max(ans,res);
    	return;
    }
    void dfs(int pos)
    {
    	if(pos == n + 1){solve();return;}
    	sel[pos] = true;dfs(pos + 1);
    	sel[pos] = false;dfs(pos + 1);
    	return;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i = 1;i <= n;++i)scanf("%lld%lld%lld",&q[i].t,&q[i].g,&q[i].m);
    	sort(q + 1,q + 1 + n,cmp);
    	dfs(1);
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    386. Lexicographical Numbers 输出1到n之间按lexico排列的数字序列
    287. Find the Duplicate Number 找出数组中的重复数字
    165. Compare Version Numbers比较版本号的大小
    java之spring mvc之文件上传
    java之spring mvc之Restful风格开发及相关的配置
    java之spring mvc之页面跳转
    java之spring mvc之数据处理
    java之spring mvc之Controller配置的几种方式
    java之spring mvc之helloworld
    java之spring mvc之初始spring mvc
  • 原文地址:https://www.cnblogs.com/wjh15101051/p/13528580.html
Copyright © 2011-2022 走看看