[关闭]
@994495jj 2017-05-31T11:45:56.000000Z 字数 1209 阅读 904

codeforces 808E Selling Souvenirs

(ACM)二分



题意

题解

代码

  1. #include<map>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. const int N=100005;
  8. int n,m;
  9. int a[4][N];
  10. ll sum[4][N];
  11. int main() {
  12. while(~scanf("%d%d",&n,&m)) {
  13. ///init
  14. memset(a,0,sizeof(a));
  15. memset(sum,0,sizeof(sum));
  16. ///read
  17. for(int i=1;i<=n;++i) {
  18. int w,c;scanf("%d%d",&w,&c);
  19. a[w][++a[w][0]]=-c;
  20. }
  21. ///sort
  22. for(int i=1;i<=3;++i) {
  23. sort(a[i]+1,a[i]+1+a[i][0]);
  24. }
  25. ///get sum
  26. for(int i=1;i<=3;++i) {
  27. for(int j=1;j<=a[i][0];++j) {
  28. sum[i][j]=sum[i][j-1]-a[i][j];
  29. }
  30. }
  31. ///solve
  32. ll ans=0;
  33. for(int c3=0;c3<=a[3][0];++c3) {//for w==3
  34. if(c3*3>m) break;
  35. int k=m-c3*3;
  36. ///bin
  37. int l=1,r=min(k/2,a[2][0]),c2=0;
  38. while(l<=r) {
  39. int mid=(l+r)>>1;
  40. int t=-a[2][mid];
  41. int prec2=mid-1;
  42. int prec1=k-prec2*2;
  43. if(1<=prec1&&prec1<=a[1][0]) t=t+a[1][prec1];
  44. if(1<=prec1-1&&prec1-1<=a[1][0]) t=t+a[1][prec1-1];
  45. if(t>0) {
  46. c2=mid;
  47. l=mid+1;
  48. } else {
  49. r=mid-1;
  50. }
  51. }
  52. ///upd
  53. int c1=k-c2*2;
  54. if(c1>a[1][0]) c1=a[1][0];
  55. if(c2>a[2][0]) c2=a[2][0];
  56. ans=max(ans,sum[1][c1]+sum[2][c2]+sum[3][c3]);
  57. }
  58. ///print
  59. printf("%I64d\n",ans);
  60. }
  61. return 0;
  62. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注