[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;
}
标签:ch,int,namespace,ARC085E,isdigit,MUL,getchar
From: https://www.cnblogs.com/DCH233/p/17189199.html