YY_More

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

这道题目其实就是裸的凸完全单调性,显然是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;
}
posted on 2011-08-03 15:01  YY_More  阅读(570)  评论(0编辑  收藏  举报