题源


 

 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] 

posted @ 2020-01-12 20:52  monyhzc  阅读(182)  评论(0编辑  收藏  举报