您的位置:首页 > 其它

BZOJ 1563 诗人小G

2017-03-23 09:42 253 查看
标准的1d/1d形式,具有决策单调性,二分栈优化nlogn。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100050
#define inf 1000000000000000000LL
using namespace std;
int t,n,l,p,s[maxn],top=0,sum[maxn],g[maxn];
char sj[maxn];
long double dp[maxn];
long double calc(int i,int j)
{
long double ret=sum[i]-sum[j]+i-j-l-1;ret=fabs(ret);long double ans=1.0;
for (int i=1;i<=p;i++) ans=ans*ret;
return ans+dp[j];
}
int get_pos(int x)
{
int l=1,r=top,ans=-1;
while (l<=r)
{
int mid=(l+r)>>1;
if (g[s[mid]]<=x) {ans=s[mid];l=mid+1;}
else r=mid-1;
}
return ans;
}
int get_di(int l,int r,int x,int y)
{
int ans;
while (l<=r)
{
int mid=(l+r)>>1;
if (calc(mid,x)<calc(mid,y)) {ans=mid;l=mid+1;}
else r=mid-1;
}
return ans+1;
}
void work()
{
memset(dp,0,sizeof(dp));memset(sum,0,sizeof(sum));memset(g,0,sizeof(g));
scanf("%d%d%d",&n,&l,&p);
for (int i=1;i<=n;i++) {scanf("%s",sj);sum[i]=sum[i-1]+strlen(sj);}
top=1;s[1]=0;g[0]=1;
for (int i=1;i<=n;i++)
{
int ret=get_pos(i);dp[i]=calc(i,ret);
while (g[s[top]]>i && calc(g[s[top]],s[top])>calc(g[s[top]],i)) s[top--]=0;
int pos=get_di(max(g[s[top]],i),n,s[top],i);
if (pos==n+1) continue;
s[++top]=i;g[s[top]]=pos;
}
if (dp
-0.5>inf) printf("Too hard to arrange\n");
else printf("%lld\n",(long long)dp
);
printf("--------------------\n");
}
int main()
{
scanf("%d",&t);
for (int i=1;i<=t;i++) work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: