JZOJ 1756.得分
2016-02-18 13:33
239 查看
Description
现在yk手上有N道题,他总共有T的时间来完成他们中的一些或全部。每道题有一个完成所需时间t[i]和一个难度系数c[i]。如果yk在剩余x个单位时间的时候开始做题i,并且能够完成,那么总分加上x*c[i]。现在yk要从这N道题中选出一些在T个单位时间内完成,并且按照某种顺序依次完成它们(yk每个单位时间只能做一道题,并且一旦他决定做某题就会一直做直到做完),那么他最多能够拿到多少分呢?Input
第一行,两个用空格隔开的正整数N和T,分别表示题目总数和总时间。第2到N+1行,每行包含两个正整数,第i+1行的两个正整数分别表示t[i]和c[i]
Output
一行一个整数,表示最大能够得到的分数Sample Input Output
输入1:3 10
2 1
8 9
2 5
输出1:
122
Hint
最优方案为在剩余10个单位时间的时候开始做第3题(需要2个单位时间),剩余8个单位时间的时候开始做第2题(需要8个单位时间),总得分为10×5+(10-2)×9=122。输入2:
3 12
3 6
7 5
4 2
输出2:
117
Data Constraint
对于20%的数据,N≤8,T≤200。对于40%的数据,N≤15,T≤1000。
对于另外30%的数据,N≤2000且满足T不小于做完N道题所需时间的总和。
对于全部的数据,N≤3000,T≤10000,所有的ti和ci均不超过100。
Solution
证明选择顺序的结论
首先我们按照C[i]/T[i]从大到小排一个序,因为先选择前面的题是较优的。证明过程:
假如有i,j (i<j),c[i]/t[i]>c[j]/t[j],则有C[i]T[j]>C[j]T[i]。
假设剩余x分钟,剩余i,j两道题未选,则先选i是较优的。
我们可以将表示先选i和先选j获得的得分的式子列出来:
先选i,则价值为x* C[i]+(X-T[i])*C[j] 拆开后得到 xC[i]+xC[j]-C[j]T[i]
先选j,则价值为x* C[j]+(X-T[j])*C[i] 拆开后得到 xC[i]+xC[j]-C[i]T[j]
∵C[i]T[j]>C[j]T[i]
∴-C[i]T[j]<-C[j]T[i]
∴先选i的价值比先选j的得分多。
∴以先选i是较优的
接下来我们打背包。设F[j]为**剩余**j分钟,所得得分的最大值,则选完前i-1题的最高得分为F[j+t[i]],得分则为(j+t[i]-1)*C[i],答案就是f[j]的最大值。
Code
var f:array[0..10000] of longint; v,w:array[0..3001] of longint; g:array[0..3001] of extended; i,j,k,l,n,m,t,ans:longint; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; procedure qsort(l,r:longint); var i,j:longint; mid:extended; begin i:=l; j:=r; mid:=g[(l+r)div 2]; repeat while (g[i]>mid) do inc(i); while (g[j]<mid) do dec(j); if i<=j then begin w[0]:=w[i];w[i]:=w[j];w[j]:=w[0]; v[0]:=v[i];v[i]:=v[j];v[j]:=v[0]; g[0]:=g[i];g[i]:=g[j];g[j]:=g[0]; inc(i);dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; begin readln(n,t); fillchar(f,sizeof(f),128); f[t+1]:=0; for i:=1 to n do begin readln(v[i],w[i]); g[i]:=w[i]/v[i]; end; qsort(1,n); for i:=1 to n do begin for l:=1 to t do begin f[l]:=max(f[l],f[l+v[i]]+(l+v[i]-1)*w[i]); if f[l]>ans then ans:=f[l]; end; end; writeln(ans); end.
——2016.2.18 By Wzy
相关文章推荐
- [算法学习]后缀表达式转二叉树
- POJ-3292-Semi-prime H-numbers-数筛法
- Android手机重启的核心代码
- 字符编码的历史演变
- sqlite 取得结果集行号的方法
- IOS 单选框
- test
- [坑]微信支付首次支付成功,第二次调用失败
- 从运行原理及使用场景看Apache和Nginx
- nyoj 38 布线问题 克鲁斯卡尔
- 6.Tachyon文件存储以及读写过程
- Git -- 工作区 和 暂存区
- Java 反射
- 使用ServiceStack构建Web服务
- loadView重写
- Java线程(七):Callable和Future
- 网络I/O模型
- SRGB和RGB的区别
- AppDelegate中的生命周期事件的调用条件
- 5.Tachyon参数配置