P2123 ----- 赌神与hack的搏斗 2
MoCaRabbit · · 题解
P1561 ----- 赌神与hack的搏斗。
这道题是与 P1561 相同的大水题。
在上面链接的题解中,有讲 Johnson 不等式与 knuth 算法随机化。
先用 Johnson 不等式排序。
用 knuth 算法随机打乱序列去做。
改一下输入与多测,交一发。
95 pts。
这题 Hack 数据显然比上题要大。
LBY 这个蒟蒻尝试了几十次,终于,一个能通过的简单的随机算法来了。
按照 dalao 说的,Johnson 不等式不具有不具有不可比性的传递性。
所以在不同序列上,有不同的答案。
于是我们在每次 knuth 后,直接用 Johnson 排一下序。
我不信还不能排出所有序列。
于是就过了。
AC 记录。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
struct node{
int a,b;
}a[20010];
inline void knuth(){//knuth算法
for(int i=1;i<=n;i++)
swap(a[1],a[rand()%n+1]);
}
inline int count(){
int sum=0,ans=0;
for(int i=1;i<=n;i++){
sum+=a[i].a;
ans=max(ans,sum)+a[i].b;
}
return ans;
}
bool cmp(node x,node y){
return (min(x.a,y.b)<min(x.b,y.a)) ? 1 : 0;
}
inline void solve(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].a>>a[i].b;
sort(a+1,a+n+1,cmp);
int cnt=0,ans=2e15;
while(cnt+2*n<=2e6){//时间足够就继续枚举
cnt+=2*n;
int p=count();
ans=min(ans,p);
knuth();
sort(a+1,a+n+1,cmp);
}
cout<<ans<<"\n";
}
signed main() {
ios::sync_with_stdio(0);
srand(time(0));
int t;
cin>>t;
while(t--) solve();
return 0;
}
细节
首先,这份代码需要你有把控时间的能力。
你需要判断这个时间是否能过。
第二,把打乱时间的
第三,inline 与 ios 优化才能过,这种需要足够的卡常。