Live2d Test Env

BZOJ - 4518: 征途(斜率优化,求N数划分为M区间的最小方差)

 

注意初始化。。。等等补

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=3010;
int q[maxn],head,tail;
ll s[maxn],s2[maxn],dp[maxn][maxn];
ll getans(int i,int j,int k){ return dp[i-1][k]+(s[j]-s[k])*(s[j]-s[k]); }
double dy(int i,int x,int y){ return ((double)(dp[i][x]+s2[x]-dp[i][y]-s2[y]))/(double)(s[x]-s[y]); }
int main()
{
    int N,M,i,j;
    scanf("%d%d",&N,&M);
    memset(dp,0x3f,sizeof(dp)); dp[0][0]=0; //初始化,避免出现i>j的情况 
    for(i=1;i<=N;i++) scanf("%lld",&s[i]),s[i]+=s[i-1],s2[i]=s[i]*s[i];
    for(i=1;i<=M;i++){
        head=tail=0;
        for(j=1;j<=N;j++){
            while(head<tail&&getans(i,j,q[head])>getans(i,j,q[head+1])) head++;
            while(head<tail&&dy(i-1,j,q[tail])<dy(i-1,q[tail],q[tail-1])) tail--;
            q[++tail]=j; dp[i][j]=getans(i,j,q[head]);
        }
    }
    printf("%lld\n",dp[M][N]*M-s2[N]);
    return 0;
}

 

posted @ 2018-07-18 12:48  nimphy  阅读(323)  评论(0编辑  收藏  举报