这道题目其实就是裸的凸完全单调性,显然是O(nlogn)的算法。
但是这个倒霉题目卡了我2天。昨天写的程序WA了,所以今天完全推倒重写,但是居然又WA了。
太蛋疼了,居然用long double才够用,还要考虑蛋疼的精度问题,最后好不容易改对了,结果又被lld和I64d虐了。
最蛋疼的是,当我发现直接成为rank1之后,想优化一下代码,结果用的是小号交的。。。就这么被马甲虐了,怎么也上不去了。。。
//By YY_More #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct node{ int s,t,k; } now,D[100001]; char s[32]; int N,P,LL,T,head,tail,sum[100001]; long double F[100001]; inline long double cal(int a,int b){ long double temp=fabs(sum[b]-sum[a-1]+(b-a)-LL),ans=1; for (int h=1;h<=P;h++) ans*=temp; return ans; } int main(){ scanf("%d",&T); while (T--){ scanf("%d%d%d",&N,&LL,&P); getchar(); for (int i=1;i<=N;i++){ gets(s); sum[i]=sum[i-1]+strlen(s); } head=tail=0;D[0].s=1;D[0].t=N; for (int i=1;i<N;i++){ while (i>D[head].t) head++; F[i]=F[D[head].k]+cal(D[head].k+1,i); if (F[i]+cal(i+1,N)>=F[D[tail].k]+cal(D[tail].k+1,N)) continue; while (D[tail].s>i&&F[D[tail].k]+cal(D[tail].k+1,D[tail].s)>F[i]+cal(i+1,D[tail].s)) tail--; int L=max(i+1,D[tail].s),R=D[tail].t,mid; while (L<R){ mid=(L+R)>>1; if (F[D[tail].k]+cal(D[tail].k+1,mid)>F[i]+cal(i+1,mid)) R=mid;else L=mid+1; } if (F[i]+cal(i+1,L)>=F[D[tail].k]+cal(D[tail].k+1,L)) L++; D[tail].t=L-1;D[++tail].k=i;D[tail].s=L;D[tail].t=N; } while (N>D[head].t) head++; F[N]=F[D[head].k]+cal(D[head].k+1,N); if (F[N]>1000000000000000000.0) printf("Too hard to arrange\n"); else printf("%lld\n",(long long)F[N]); printf("--------------------\n"); } return 0; }