[ARC085E] MUL

[ARC085E] MUL

随机化贪心初探,真不错。

有一个显然的贪心:每次选一个数,考虑删去它的倍数是否能使答案更优,然后贪心做,这样显然是错的。

但是我们乱搞一下,每次做之前随机一个排列,按照排列的顺序做,然后做个好多次,就对了!

参考代码:

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
 
namespace IO {
  #define isdigit(x) (x >= '0' && x <= '9')
  template<typename T>
  inline void read(T &x) {
    x = 0; char ch = getchar(); int f = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
  }
  template<typename T>
  inline void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
  }
  #undef isdigit
}
using namespace IO;
 
const int N = 110;
int n, a[N], tp[N], p[N];
 
mt19937 rnd(time(0));
 
int main() {
  read(n);
  LL s = 0;
  for(int i = 1; i <= n; ++i)
    read(a[i]), p[i] = i, s += a[i];
  int T = 50000;
  LL ans = 0;
  while(T--) {
    shuffle(p + 1, p + n + 1, rnd);
    for(int i = 1; i <= n; ++i) 
      tp[i] = 0;
    LL cur = 0;
    for(int k = 1; k <= n; ++k) {
      int i = p[k];
      LL sum = 0;
      for(int j = i; j <= n; j += i) 
        if(!tp[j]) sum += a[j];
      if(sum < 0)
        for(int j = i; j <= n; j += i)
          if(!tp[j]) tp[j] = 1, cur += a[j];
    } 
    ans = max(ans, s - cur);
  }
  printf("%lld\n",ans);
  return 0;
}
posted @ 2023-03-07 18:52  DCH233  阅读(19)  评论(0编辑  收藏  举报