DP_1d1d诗人小G
2024-09-06 19:23:25
显然:f[i]=min{f[j]+(s[i]-s[j]+i-j-1-l)^p}
此题可以基于决策单调优化
实际上就是双向队列
不停弹出队头的元素,直到当前位置在队头元素最优的范围内。
然后,每次把当前决策插入队尾,并弹出没它优的答案。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std; typedef long double ll;
const int MAXN=1e5+;
struct node{int l,r,p;}q[MAXN];
ll sum[MAXN],f[MAXN];
int T,n,l,p;
char s[]; ll pow(ll x){
int y=p;ll ret=;
while(y){
if(y&)ret=ret*x;
x*=x,y>>=;
}
return ret;
} ll calc(int x,int y){
return f[x]+pow(abs(sum[y]-sum[x]+(y-x-)-l));
} int find(node x,int i){
int l=x.l,r=x.r;
while(l<=r){
int mid=(l+r)>>;
if(calc(i,mid)<=calc(x.p,mid))r=mid-;
else l=mid+;
}
return l;
} void DP_1d1d(){
int head=,tail=;
q[++tail]=(node){,n,};
for(int i=;i<=n;i++){
if(head<=tail && q[head].r<i)head++;
f[i]=calc(q[head].p,i);
if(calc(i,n)<=calc(q[tail].p,n)){
while(head<=tail && calc(q[tail].p,q[tail].l)>=calc(i,q[tail].l) )tail--;
if(head>tail)q[++tail]=(node){i,n,i};
else{
int x=find(q[tail],i);
q[tail].r=x-;
q[++tail]=(node){x,n,i};
}
}
}
} int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&l,&p);
for(int i=;i<=n;i++)scanf("%s",s),sum[i]=sum[i-]+strlen(s);
DP_1d1d();
if(f[n]>1e18)puts("Too hard to arrange");
else printf("%lld\n",(long long)f[n]);
puts("--------------------");
}
return ;
}
DP_1d1d
最新文章
- [LeetCode]Lowest Common Ancestor of a Binary Search Tree
- nodejs-2:模块与包管理工具
- labview学习_入门篇(一)
- css/js(工作中遇到的问题)-3
- 尝试制作了一个Panorama
- Linux运维操作
- 2016年11月27日 星期日 --出埃及记 Exodus 20:18
- 通过 Javacore 诊断线程挂起等性能问题
- [物理学与PDEs]第1章 电动力学
- iOS组件化思路-大神博客研读和思考
- java高级:weakReference
- BZOJ 1602: [Usaco2008 Oct]牧场行走( 最短路 )
- 201521123087《Java程序设计》第14周学习总结
- kubernetes入门(06)kubernetes的核心概念(3)
- 生活日历NABCD需求分析
- Python 30分钟快速入门指南
- django2.0.6 连接使用redis集群
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
- cf666 C. Codeword 组合数学
- 继承映射中的java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: person is not mapped [FROM person]