[APIO2014]序列分割 题解

发现答案最终形如xy+yz+xz,与顺序无关

斜率优化DP显然

坑点是当分母为0时不可以把斜率当成inf,要当成-inf,即直接约分会错

艹因为这个坑小破题调了一下午……

强行深入理解斜率优化(大雾

#include<iostream>
#include<cstdio>
using namespace std;

const int maxn = 100005;
const int maxm = 205;
int n, m, pre[maxm][maxn], q[maxn];
long long int s[maxn], dp[maxm][maxn];

void do_it(int x) {
    int ll=1, rr=0, i, y, z;
    for(i=x-1; i <= n; i++) {
        y=q[ll]; z=q[ll+1];
        while(ll < rr && 
         ((dp[x-1][y]-s[y]*s[y]) - (dp[x-1][z]-s[z]*s[z])
          < s[i]*(s[z]-s[y]) 
          || s[z] == s[y])
        ) {
            ll++;
            y=q[ll]; z=q[ll+1];
        }
        if(ll <= rr) {
            y=q[ll];
            dp[x][i] = dp[x-1][y]+s[y]*(s[i]-s[y]);
            pre[x][i]=y;
            //cout<<ll<<' '<<rr<<';'<<y<<' '<<i<<endl;
            //cout<<dp[x][i]<<endl;
        }
        y=q[rr-1]; z=q[rr];
        while(ll < rr && 
         ((((dp[x-1][y]-s[y]*s[y]) - (dp[x-1][z]-s[z]*s[z]) )*(s[i]-s[z]) 
          > ((dp[x-1][z]-s[z]*s[z]) - (dp[x-1][i]-s[i]*s[i]) ) *(s[z]-s[y]) 
          && s[z] != s[y]) || s[i] == s[z])
        ) {
            rr--;
            y=q[rr-1]; z=q[rr];
        }
        rr++;
        q[rr]=i;
    }
    return;
}

int main() {
    int i, t;
    cin>>n>>m;
    m++;
    for(i=1; i <= n; i++) {
        cin>>s[i]; s[i]+=s[i-1];
    }
    
    for(i=2; i <= m; i++) do_it(i);// cout<<endl;
    
    cout<<dp[m][n]<<endl;
    t=n;
    for(i=m; i >= 2; i--) {
        cout<<pre[i][t]<<' ';
        t=pre[i][t];
    }
    cout<<endl;
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/crraphael/p/11364414.html
0条评论
添加一条新回复