[关闭]
@wsndy-xx 2018-05-19T08:53:35.000000Z 字数 2031 阅读 891

Luogu 最大收益

题解

吐槽

模拟退火
崩溃

正解是DP
Dp方程明显

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<stdio.h>
  4. using namespace std;
  5. const int maxn=3001;
  6. struct proj {
  7. int w,r;
  8. } a[maxn];
  9. bool cmp(const proj &a,const proj &b) {
  10. return a.r>b.r;
  11. }
  12. int f[maxn][maxn];
  13. int n,ans;
  14. void solve() {
  15. cin>>n;
  16. for(int i=1; i<=n; i++) cin>>a[i].w>>a[i].r;
  17. sort(a+1,a+1+n,cmp);
  18. f[1][1]=a[1].w;
  19. for(int i=1; i<=n; i++) for(int j=1; j<=i; j++)
  20. f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i].w-a[i].r*(j-1));
  21. for(int i=1; i<=n; i++) ans=max(f[n][i],ans);
  22. cout<<ans;
  23. }
  24. int main() {
  25. solve();
  26. return 0;
  27. }

那个T到飞起的模拟退火
只好把 改的小一点,那就 WA 了
这份代码50
好像只有暴力分

  1. #include <bits/stdc++.h>
  2. const int N = 3010 << 2;
  3. #define DB double
  4. const DB Delta = 0.98;
  5. const DB eps = 1e-10;
  6. const DB Delta2 = 0.88;
  7. const DB eps2 = 1e-5;
  8. int W[N], R[N];
  9. int n;
  10. bool Use[N];
  11. int Beuse[N], Sum[N];
  12. #define gc getchar()
  13. inline int read() {
  14. int x = 0; char c = gc;
  15. while(c < '0' || c > '9') c = gc;
  16. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
  17. return x;
  18. }
  19. inline int Work_2() {
  20. DB Now_temp = 1000;
  21. int js(0), cut(0);
  22. for(int i = 1; i <= n; ++ i) Sum[i] = 0;
  23. for(int i = 1; i <= n; ++ i) if(Use[i]) Beuse[++ js] = i;
  24. if(js == 1) return W[Beuse[1]];
  25. for(int i = 1; i <= js; ++ i) Sum[i] = Sum[i - 1] + W[Beuse[i]], cut += (js - i) * R[Beuse[i]];
  26. int Ans = Sum[js] - cut;
  27. while(Now_temp > eps2) {
  28. int R1 = rand() % js + 1, R2 = rand() % js + 1;
  29. while(R2 == R1) R2 = rand() % js + 1;
  30. if(R1 > R2) std:: swap(R1, R2);
  31. int delta = (js - R1) * (R[Beuse[R1]] - R[Beuse[R2]]) + (js - R2) * (R[Beuse[R2]] - R[Beuse[R1]]);
  32. if(delta > 0 || (exp((DB)-delta / Now_temp) * RAND_MAX < rand())) {
  33. std:: swap(Beuse[R1], Beuse[R2]);
  34. Ans += delta;
  35. }
  36. Now_temp *= Delta2;
  37. }
  38. return Ans;
  39. }
  40. int tot;
  41. inline int Work_1() {
  42. DB Now_temp = 1000;
  43. tot = 0;
  44. for(int i = 1; i <= n; ++ i) Use[i] = 0;
  45. Use[rand() % n + 1] = 1;
  46. for(int i = 1; i <= n; ++ i) {
  47. if(!Use[i]) Use[i] = rand() % 2;
  48. if(Use[i]) tot ++;
  49. }
  50. int Ans = Work_2();
  51. while(Now_temp > eps) {
  52. int R1 = rand() % n + 1;
  53. if(Use[R1]) tot --;
  54. else tot ++;
  55. Use[R1] ^= 1;
  56. if(!tot) {Use[R1] ^= 1; Now_temp *= Delta; tot ++; continue ;}
  57. int NxtAns = Work_2();
  58. if(NxtAns > Ans || (exp((DB)(Ans - NxtAns) / Now_temp) * RAND_MAX < rand())) Ans = NxtAns;
  59. else {Use[R1] ^= 1; if(Use[R1]) tot ++; else tot --;}
  60. Now_temp *= Delta;
  61. }
  62. return Ans;
  63. }
  64. int main() {
  65. srand(time(0) + 20001206);
  66. n = read();
  67. for(int i = 1; i <= n; ++ i) W[i] = read(), R[i] = read();
  68. int T = 30;
  69. int Answer = 0;
  70. for(; T; T --)
  71. Answer = std:: max(Answer, Work_1());
  72. std:: cout << Answer;
  73. return 0;
  74. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注