诗人小G

诗人小G

考虑普通的 DP。令 \(f_i\) 表示划分前 \(i\) 个句子的最小不协调度。可以用前缀和处理,易得方程 \(f_i=f_j+| s_i-s_j+i-j-1-l|^p\),注意这里空格是需要考虑长度的,也就是 \(j+1\sim i\) 成立了一段,那么应该是 \(i-(j+1)+1-1=i-j-1\) 个空格。

接下来考虑用四边形不等式优化。
首先对于那个 \(f_j\) 后面的恶心的式子就不证明了,考试时强烈建议打表。具体可以看 AcWing。接下来就是需要用到四边形不等式的性质:决策单调性,即 \(p_i\) 严格不降。我们可以用若干段区间 \([j,l,r]\) 表示这段区间 \([l,r]\) 内的决策是 \(j\)。当然这个只存储处理了前 \(i\) 个的情况。每次新加入一个数 \(i\),需要先检查队首元素的下标是否 \(\le i\),进行更新。然后是队尾,每次看这段区间的左端点的取值用 \(i\) 是否更优,如果是就删去这段区间,如果不是就看一下右端点是否用 \(i\) 更优,如果是就二分寻找中间的分界点。最后把删去的区间用 \(i\) 决策合并起来加回去。均摊是 \(O(n\log n)\)。代码有点麻烦。

#include<bits/stdc++.h>
using namespace std;
#define L(i,l,r) for(int i=l;i<=r;++i)
#define R(i,l,r) for(int i=r;i>=l;--i)
const int N=100010;
typedef long double ll;
int n,L,P,p[N],s[N],hh,tt;
ll f[N];
char str[N][31];
struct node{
    int j,l,r;
}q[N];
ll val(int j,int i){
    ll res=1,a=abs(s[i]-s[j]+i-j-1-L);
    L(i, 1, P)res*=a;
    return res+f[j];
}
void insert(int i){
    int pos=n+1;
    while(hh<=tt&&val(q[tt].j,q[tt].l)>=val(i,q[tt].l))pos=q[tt--].l;
    if(hh<=tt&&val(q[tt].j,q[tt].r)>=val(i,q[tt].r)){
        int l=q[tt].l,r=q[tt].r;
        while(l<r){
            int mid=(l+r)>>1;
            if(val(q[tt].j,mid)>=val(i,mid))r=mid;
            else l=mid+1;
        }
        q[tt].r=r-1;
        pos=r;
    }
    if(pos!=n+1)q[++tt]={i,pos,n};
}
int main(){
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&L,&P);
        R(i, 1, n)scanf("%s",str[i]);
        L(i, 1, n)s[i]=s[i-1]+strlen(str[i]);
        hh=tt=0;
        q[0]={0,1,n};
        L(i, 1, n){
            f[i]=val(q[hh].j,i),p[i]=q[hh].j;
            if(q[hh].r==i)++hh;
            q[hh].l=i+1;
            insert(i);
        }
        if(f[n]>1e18)puts("Too hard to arrange");
        else{
            printf("%lld\n",(long long)f[n]);
            for(int i=n;i;i=p[i])
                R(j, p[i]+1, i)
                    printf("%s%c",str[j],(j==p[i]+1)?'\n':' ');
        }
        puts("--------------------");
    }
    return 0;
}
posted @ 2023-04-10 21:48  wscqwq  阅读(16)  评论(0编辑  收藏  举报