决策单调性总结
决策单调性,通常用于。
就是说,对于任意,若满足在c处转移到b比a优,那么在d处也满足。
另外一种理解:转移决策点单调不降。
证明:主要靠打表。
得到这个性质后,我们有两种方法:
1、分治法
每次取分治区间的中点,并暴力在可行区间内找到它的最优转移位置。
之后,根据这个位置,分治两边的位置,并缩小可行区间的范围。
时间复杂度:。
并且,它满足一个性质:若转移点为,那么的移动距离之和为,即均摊,有时可以用类似莫队的方法。
优点:好写,好理解,并且找转移位置是连续寻找的,有的问题会比较方便。
缺点:要求dp之间没有依赖(即没有计算顺序的要求),比如多阶段dp。
2、二分+双端队列法
我们按照顺序进行dp,并维护每个位置当前状态下的最优转移位置。
当计算到时:
首先,算出。
其次,算出用它转移的区间。根据定义,只要找到第一个用转移比当前更优的位置,那么之后的都是由它转移更优。
这个位置可以使用二分查找。
因此,我们需要实现后缀覆盖,单点查询。似乎不容易。
由于后缀覆盖具有均摊性,我们考虑维护转移位置相同的若干段。
维护一个队列,每个节点记录它对应的区间,和转移位置。
在二分查找时,我们从队尾反向遍历,并在这个区间内二分查找,若找不到,则退出。否则,把这个从队尾扔出。
若没有完全覆盖,则把这个区间缩小。最后,在队尾加入当前区间。
注意:
1、在依次计算dp时,要把队首没用的弹出。
2、在二分查找时,左端点要和取。
3、要特判不能更新任何位置的情况。
优点:适用情况更普遍,比如诗人小G
缺点:细节较多,难以理解,相对难写。
刚才那题的代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define max(a,b) a>b?a:b
#define ld long double
ld dp[100010];
ld ksm(ld a,int b)
{
ld jg=1;
while(b>0)
{
if(b&1)
jg*=a;
a*=a;b=(b>>1);
}
return jg;
}
char zf[100010][31];
int he[100010],wz[100010],st[100010],l,p;
ld cal(int i,int j)
{
return dp[j]+ksm(fabs((he[i]-he[j]-1)-l),p);
}
struct SJd
{
int l,r,z;
SJd(){}
SJd(int L,int R,int Z)
{
l=L;r=R;z=Z;
}
};
SJd dl[200010];
int efcz(int l,int r,int x,int y)
{
while(l<r)
{
int m=(l+r)>>1;
if(cal(m,x)<cal(m,y))
r=m;
else
l=m+1;
}
return l;
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&l,&p);
for(int i=1;i<=n;i++)
{
scanf("%s",zf[i]);
he[i]=strlen(zf[i])+he[i-1]+1;
}
dl[0]=SJd(1,n,0);
for(int i=1,he=0,ta=1;i<=n;i++)
{
while(he<ta&&i>dl[he].r)
he+=1;
int j=dl[he].z,zd=false;
dp[i]=cal(i,j);wz[i]=j;
while(he<ta&&efcz(max(dl[ta-1].l,i+1),dl[ta-1].r+1,i,dl[ta-1].z)<=dl[ta-1].r)
ta-=1,zd=true;
if(!zd)continue;
int l=efcz(max(dl[ta].l,i+1),dl[ta].r,i,dl[ta].z);
if(l>dl[ta].l)
dl[ta++].r=l-1;
dl[ta++]=SJd(l,n,i);
}
if(dp[n]>1e18)
printf("Too hard to arrange\n");
else
{
printf("%.0Lf\n",dp[n]);
int u=n,m=0;
while(u>0)
{
st[m++]=u;
u=wz[u];
}
for(int i=m-1,la=0;i>=0;i--)
{
for(int j=la+1;j<=st[i];j++)
{
printf("%s",zf[j]);
if(j<st[i])printf(" ");
}
la=st[i];
printf("\n");
}
}
printf("--------------------");
if(T>0)printf("\n");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!