NC19923. [CQOI2012]模拟工厂
描述
输入描述
输入第一行包含一个整数n,即订单数目。以下n行每行三个整数ti, gi, mi。
输出描述
输出仅一行,为最大总收入。输出保证在32位带符号整数范围内。
示例1
输入:
2 5 1 8 7 15 3
输出:
11
C++11(clang++ 3.9) 解法, 执行用时: 8ms, 内存消耗: 488K, 提交时间: 2020-03-29 00:04:20
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> #define ll long long using namespace std; ll n; struct data { ll tim,g,m; bool operator <(const data tmp)const { return tim<tmp.tim; } }t[20]; int q[20],tot; ll gets(ll a,ll b,ll c) { ll de=b*b-4*a*c; if(de<0) return -1; double d=sqrt(de); double x1=(-b-d)/(2.0*a),x2=(-b+d)/(2.0*a); return max((ll)floor(x1),(ll)floor(x2)); } ll ans=0; void solve(int x) { ll sum=0,tot=0; for(int i=1;i<=n;i++) if((1<<(i-1))&x) q[++tot]=i; ll s=0,g=1; for(int i=1;i<=tot;i++) { ll tmp=2147483647ll,now=0; for(int j=i;j<=tot;j++) { now+=t[q[j]].g; ll b=t[q[j]].tim-t[q[i-1]].tim; tmp=min(tmp,gets(-1,b-g,b*g+s-now)); if(tmp<0) { sum=0; return; } } g+=tmp; s+=g*(t[q[i]].tim-t[q[i-1]].tim-tmp); sum+=t[q[i]].m; s-=t[q[i]].g; } ans=max(ans,sum); } int main() { scanf("%lld",&n); for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&t[i].tim,&t[i].g,&t[i].m); sort(t+1,t+n+1); for(int i=0;i<=(1<<n)-1;i++) solve(i); printf("%lld",ans); }