bzoj1563: [NOI2009]诗人小G
f[i]表示前i句诗的最小不协调度,f[i]=min(0<=j<i){f[j]+|s[i]-s[j]+i-j-1-L|^p}
val(j,i)=|s[i]-s[j]+i-j-1-L|^p 满足四边形不等式
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long double LD; int P; LD quick_pow(LD A) { LD ret=1;int p=P; while(p!=0) { if(p%2==1)ret*=A; A*=A;p/=2; } return ret; } int n,s[110000];LD L,f[110000]; LD myabs(LD x){return x<0?-x:x;} LD val(int j,int i){return quick_pow(myabs(s[i]-s[j]+i-j-1-L));} struct node { int id,l,r; node(){} node(int ID,int L,int R){id=ID;l=L;r=R;} }q[110000];int h,t; char ss[3100000]; int main() { freopen("poet.in","r",stdin); freopen("poet.out","w",stdout); int T; scanf("%d",&T); while(T--) { scanf("%d%Lf%d",&n,&L,&P); s[0]=0; for(int i=1;i<=n;i++) scanf("%s",ss+1), s[i]=s[i-1]+strlen(ss+1); h=1,t=0;q[++t]=node(0,0,n); for(int i=1;i<=n;i++) { if(q[h].r<i)h++; q[h].l=i;f[i]=f[q[h].id]+val(q[h].id,i); if(h>t||f[i]+val(i,n)<=f[q[t].id]+val(q[t].id,n)) { while(h<=t&&f[i]+val(i,q[t].l)<=f[q[t].id]+val(q[t].id,q[t].l))t--; if(h>t)q[++t]=node(i,1,n); else { int l=q[t].l,r=q[t].r,ans; while(l<=r) { int mid=(l+r)/2; if(f[i]+val(i,mid)>f[q[t].id]+val(q[t].id,mid)) { ans=mid; l=mid+1; } else r=mid-1; } q[t].r=ans; q[++t]=node(i,ans+1,n); } } } if(f[n]>1e18)printf("Too hard to arrange\n"); else printf("%lld\n",(long long)f[n]); printf("--------------------\n"); } return 0; }
pain and happy in the cruel world.