P1912-[NOI2009]诗人小G【四边形不等式,单调队列】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P1912


1|1题目大意

给出n个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为x,那么代价是|xL|P

求代价和最小的方案,如果代价大于1e18则输出其他东西

1n105,1L3×106,1P10


1|2解题思路

si表示前i个字符串的长度和加i,那么有转移方程

fi=min{fj+|sisj1L|P}

这个转移很麻烦不能直接用单调队列之类的优化,但是它满足四边形不等式
wi,j=|sisj1L|P,然后满足

wi,j+wi+1,j+1wi,j+1+wi+1,j

这里就不证明了,因为证明需要用到求导。

感谢理解的话可以发现因为有个abs,所以对于一个决策来说是先下后上,而且两个决策最多只有一个交点。

所以有决策单调性,我们用单调队列维护一个该决策和它的下一个决策的交换点ki,然后每次判断新加入的点与队尾的前一个的交换点是否会代替掉队尾即可。

求交换点的话用二分就好了。

时间复杂度O(Tnlogn)

怕转移太大可以用long double存,因为如果很大的时候精度就不需要管了,我们只需要知道它是否超过1e18就好了。


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll long double using namespace std; const int N=1e5+10; int T,n,L,P,p[N],k[N],q[N]; ll f[N],s[N]; char st[N][31]; ll power(ll x,int b){ ll ans=1; while(b){ if(b&1)ans=ans*x; x=x*x;b>>=1; } return ans; } ll calc(int j,int i) {return f[j]+power(fabs(s[i]-s[j]-1-L),P);} int bound(int i,int j){ int l=i,r=n; while(l<=r){ int mid=(l+r)>>1; if(calc(i,mid)<calc(j,mid))l=mid+1; else r=mid-1; } return l; } void print(int n){ if(!n)return;print(p[n]); for(int i=p[n]+1;i<n;i++) printf("%s ",st[i]); puts(st[n]); } int main() { scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&L,&P); for(int i=1;i<=n;i++){ scanf("%s",st[i]); s[i]=s[i-1]+strlen(st[i])+1; } int head=1,tail=1;q[1]=0; for(int i=1;i<=n;i++){ while(head<tail&&k[head]<=i)head++; f[i]=calc(q[head],i);p[i]=q[head]; while(head<tail&&k[tail-1]>=bound(q[tail],i))tail--; k[tail]=bound(q[tail],i);q[++tail]=i; } if(f[n]>1e18)puts("Too hard to arrange"); else printf("%lld\n",(long long)f[n]),print(n); puts("--------------------"); } return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14433059.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(51)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示