猫
input
4 6 2 1 3 5 1 0 2 1 4 9 1 10 2 10 3 12
output
3
考虑裸的dp
O(n^3) 40分
#include<stdio.h> #include<algorithm> #define ll long long #define For(i,a,b) for(register int i=(a);i<=(b);i++) #define Rof(i,a,b) for(register int i=(a);i>=(b);i--) using namespace std; const int maxn=1e5+10,maxm=5e4+10; int n,m,p,d[maxn],a[maxm],sum[maxm]; ll dp[maxm]; inline ll min(ll a,ll b){return a<b?a:b;} signed main(){ scanf("%d%d%d",&n,&m,&p); For(i,2,n){ scanf("%d",&d[i]);d[i]+=d[i-1]; } For(i,1,m){ int h,t;scanf("%d%d",&h,&t);a[i]=t-d[h]; } sort(a+1,a+1+m); For(i,1,m){ sum[i]=sum[i-1]+a[i],dp[i]=-sum[i]+a[i]*i; } For(j,2,p){ Rof(i,m,1){ For(k,j-1,i){ dp[i]=min(dp[i],dp[k]+1LL*a[i]*(i-k)+1LL*sum[k]-1LL*sum[i]); } } } printf("%lld\n",dp[m]); }
于是考虑斜率优化
因为有 dp[i]=dp[k]+a[i]*( i-k )+sum[k]-sum[i])
两个决策点就叫 K 和 L 好了
( (dp[k]+sum[k]) - (dp[l]-sum[l]) ) / ( k-l ) = a[i]