起初用slope得了65分,将斜率交叉相乘之后0分,求调
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=4e6+5;
int n,m,f[maxn],q[maxn],num[maxn];
const double eps=1e-20;
int s[maxn],h,t;
inline int Y(int i){
return f[i]+s[i];
}
inline int B(int i){
return f[i]+s[i]-i*num[i];
}
inline int X(int i){
return num[i];
}
inline double S(int x,int y){
return 1.0*(Y(x)-Y(y))/(X(x)-X(y)-eps);
}
int main(){
int T=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
int ti;cin>>ti;
T=max(T,ti);
s[ti]+=ti;
num[ti]++;
}
for(int i=1;i<=T+m;i++){
num[i]+=num[i-1];
s[i]+=s[i-1];
}
h=t=1;q[h]=0;
for(int i=1;i<=T+m;i++){
while(h<t&&(Y(q[h])-Y(q[h+1])<=i*(X(q[h])-X(q[h+1])))) ++h;
f[i]=f[q[h]]+i*num[i]-i*num[q[h]]-s[i]+s[q[h]];
while(t>h&&(Y(q[t-1])-Y(q[t]))*(X(q[t])-X(i-m+1))>=(X(q[t-1])-X(q[t]))*(Y(q[t])-Y(i-m+1)))--t;
if(i-m+1>0)q[++t]=i-m+1;
}int ans=0x7f7f7f7f;
for(int i=T;i<=T+m;i++){
ans=min(ans,f[i]);
}
cout<<ans;
return 0;
}
65分代码如下
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=4e6+5;
int n,m,f[maxn],q[maxn],num[maxn];
const double eps=1e-20;
int s[maxn],h,t;
inline int Y(int i){
return f[i]+s[i];
}
inline int B(int i){
return f[i]+s[i]-i*num[i];
}
inline int X(int i){
return num[i];
}
inline double S(int x,int y){
return 1.0*(Y(x)-Y(y))/(X(x)-X(y)-eps);
}
int main(){
int T=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
int ti;cin>>ti;
T=max(T,ti);
s[ti]+=ti;
num[ti]++;
}
for(int i=1;i<=T+m;i++){
num[i]+=num[i-1];
s[i]+=s[i-1];
}
h=t=1;q[h]=0;
for(int i=1;i<=T+m;i++){
while(h<t&&S(q[h],q[h+1])<=i) ++h;
f[i]=f[q[h]]+i*num[i]-i*num[q[h]]-s[i]+s[q[h]];
while(t>h&&S(q[t-1],q[t])>=S(q[t],i-m+1))--t;
if(i-m+1>0)q[++t]=i-m+1;
}int ans=0x7f7f7f7f;
for(int i=T;i<=T+m;i++){
ans=min(ans,f[i]);
}
cout<<ans;
return 0;
}