我的10分代码:
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=5007;
ll n, S;
ll dp[N], t[N], f[N], q[N], head=1, tail=1;
int main(){
cin>>n>>S;
for(int i=1;i<=n;i++){
cin>>t[i]>>f[i];
t[i]+=t[i-1];
f[i]+=f[i-1];
}
memset(dp, 0x3f, sizeof(dp));
dp[0]=0;
head=tail=1;
for(int i=1;i<=n;i++){
while(head<tail && dp[q[head+1]]-dp[q[head]]<=(S+t[i])*(f[q[head+1]]-f[q[head]]))//比较斜率
head++;
dp[i]=dp[q[head]]+t[i]*f[i]+S*f[n]-f[q[head]]*(S+t[i]);//放公式
while(head<tail && f[q[tail]]-f[q[tail]-1]>f[i]-f[q[tail]])
tail--;
q[++tail]=i;
}
cout<<dp[n]<<endl;
return 0;
}
但是改成
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=5007;
ll n, S;
ll dp[N], t[N], f[N], q[N], head=1, tail=1;
int main(){
cin>>n>>S;
for(int i=1;i<=n;i++){
cin>>t[i]>>f[i];
t[i]+=t[i-1];
f[i]+=f[i-1];
}
memset(dp, 0x3f, sizeof(dp));
dp[0]=0;
head=tail=1;
for(int i=1;i<=n;i++){
while(head<tail && dp[q[head+1]]-dp[q[head]]<=(S+t[i])*(f[q[head+1]]-f[q[head]]))//比较斜率
head++;
dp[i]=dp[q[head]]+t[i]*f[i]+S*f[n]-f[q[head]]*(S+t[i]);//放公式
while(head<tail && (dp[i]-dp[q[tail]])*(f[q[tail]]-f[q[tail-1]])<=(dp[q[tail]]-dp[q[tail-1]])*(f[i]-f[q[tail]]))
tail--;
q[++tail]=i;
}
cout<<dp[n]<<endl;
return 0;
}
之后就100分了
(dp[i]-dp[q[tail]])*(f[q[tail]]-f[q[tail-1]])<=(dp[q[tail]]-dp[q[tail-1]])*(f[i]-f[q[tail]])
这句话什么意思,为什么 f[q[tail]]-f[q[tail]-1]>f[i]-f[q[tail]] 就不对?