2020华中师范大学新生赛H--七日狂想曲
题面
这题我一看,最小费用流直接往上打,很快呀,然后无情TLE,十分正常,毕竟最小费用流复杂度\(O(nm^2)\),然后就看到了神仙题解思维,延迟贪心。
我首先打的最小费用流,是因为我发现了每个地方的每个药材去的地方不一样,那么就需要知道每个药材最合适的去处,那么最小费用流就可以模拟这个过程,但是复杂度不够。
然后是题解的思路
首先观察数据范围,可以看出最多\(O(n^2*log(n))\),这里开始构思算法。
对于某一个位置,我们需要对于其中每一个进出的药材进行路径选择,对于,每个拿出的药材,要么先拿出去,则当前这个药材转移的价值 \(val=b*(n-i+1)\),或者转移到一个固定的位置,那麽为了确定这个位置,枚举是不可能的,过不去的,但又有可能有这种情况,所以我们这里先暂时满足于\(val\)这个值,然后之后想办法改变,也就是贪心的思想,如果要到一个准确的地方,然后计算\(c*(i-j)-val_j\),这里从小往大枚举,可以保证以后枚举的j一定比i大,故\(|i-j|\)可以忽略 (这里可以这么做的前提是i转到j等价于j从i那获得)。
综上,
1:对于每一个需要转出的点,枚举当前的变化数目,然后\(val_i=min(b*(n-i+1,c*(i-j)-val_j)\),j是以前的已经得到应有数量的点,但\(c*(i-j)-val_j\)可以进行更少的操作次数,故这里可以更新.
2:同理,对于每个要获得的点\(val_j=min(a*i,c*(i-j)-val_j)\),
对于\(min()\)中后面的地方,我们可以用两个小根堆将\((-c*j-val_j)\)储存起来,这样每次取出时都可以保证\(c*(i-j)-val_j\)最小,这样复杂度就可以达到\(O(1e6*log(1e6))\),AC本题。
总结:这道题其实也算是到贪心,但很难想到,人还是太菜了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<bitset>
#include<queue>
#include<queue>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rpe(i,a,b) for(int i=a;i>=b;--i)
#define pts putchar('\n')
#define ptc putchar(' ')
typedef long long ll;
typedef unsigned long long ull;
const ll inf=1e18;;
const int maxn=1e3+9;
const int maxm=2e6+2;
const int mod=998244353;
const int base=131;
namespace IO{
ll read(){
ll a=1,b=0;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')a=-1;c=getchar();}
while(c>='0'&&c<='9'){b=(b<<3)+(b<<1)+c-'0';c=getchar();}
return a*b ;
}
void print (ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+'0');
}
}
using namespace IO;
ll n;
ll a,b,c;
ll u[maxn],v[maxn];
priority_queue<ll , vector<ll> , greater<ll> >q1,q2;
ll ans=0;
int main(){
//freopen("3.IN","r",stdin);
n=read(),a=read(),b=read(),c=read();
rep(i,1,n) u[i]=read();
rep(i,1,n) v[i]=read();
ll val;
rep(i,1,n){
rep(j,1,u[i]-v[i]){//向外转
val=1LL*b*(n-i+1);
if(!q2.empty()){
val=min(val,q2.top()+1LL*c*i);
q2.pop();
}
ans+=val;
q1.push(-val-1LL*c*i);
}
rep(j,1,v[i]-u[i]){
val=1LL*a*i;
if(!q1.empty()){
val=min(val,q1.top()+1LL*c*i);
q1.pop();
}
ans+=val;
q2.push(-val-1LL*c*i);
}
}
print(ans);
return 0;
}

浙公网安备 33010602011771号