悬赏5rmb求调
查看原帖
悬赏5rmb求调
490978
小超手123楼主2023/1/10 16:38
#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int n,Len;
int x[N],p[N],c[N];
int sum[N],cnt[N];
int dp[N],Q[N],head=1,tail=0;
bool check(int i,int j,int k){ //(i->j) > (j->k)
    //((dp[i]+sum[i])-(dp[j]+sum[j]))/(cnt[i]-cnt[j]) > ((dp[j]+sum[j])-(dp[k]+sum[k]))/(cnt[j]-cnt[k])
    return ((dp[i]+sum[i])-(dp[j]+sum[j]))*(cnt[j]-cnt[k]) > ((dp[j]+sum[j])-(dp[k]+sum[k]))*(cnt[i]-cnt[j]);
}
bool better(int i,int j,int t){ //i->j的斜率不合法 
    return (dp[i]+sum[i])-(dp[j]+sum[j])>=t*(cnt[i]-cnt[j]);
}
signed main(){
    //freopen("palace.in","r",stdin);
    //freopen("palace.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i]>>p[i]>>c[i];
        sum[i]=sum[i-1]+x[i]*p[i];
        cnt[i]=cnt[i-1]+p[i];
        dp[i]=c[i]+cnt[i]*x[i]-sum[i];
    }
    for(int i=1;i<=n;i++){
        while(head<tail&&better(Q[head+1],Q[head],x[i])) 
            head++;
        if(head<=tail){
            int j=Q[head];
            dp[i]=min(dp[i],dp[j]+(cnt[i]-cnt[j])*x[i]-(sum[i]-sum[j])+c[i]);
		}
		while(head<tail&&check(i,Q[tail],Q[tail-1]))
		    tail--;
		Q[++tail]=i;
	}
	cout<<dp[n];
    return 0;
}
/*
4
1 3 10
3 2 12
6 1 7
10 2 11
*/
2023/1/10 16:38
加载中...