您的位置:首页 > 其它

[BZOJ1563][NOI2009]诗人小G(决策单调性优化DP)

2018-10-22 23:49 465 查看

模板题。

每个决策点都有一个作用区间,后来的决策点可能会比先前的优。于是对于每个决策点二分到它会比谁在什么时候更优,得到新的决策点集合与区间。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long double ll;
using namespace std;

const int N=100010;
const ll MAX=1e18;
int T,n,l,p,top;
ll sm
,f
;
char ch
[35];
struct P{ int l,r,p; }q
;

ll ksm(ll x){
if (x<0) x=-x;
ll res=1; rep(i,1,p) res*=x; return res;
}

ll cal(int j,int i){ return f[j]+ksm(sm[i]-sm[j]+(i-j-1)-l); }

int find(P a,int b){
int l=a.l,r=a.r;
while (l<=r){
int mid=(l+r)>>1;
if (cal(a.p,mid)<cal(b,mid)) l=mid+1; else r=mid-1;
}
return l;
}

void DP(){
int st=1,ed=1; q[1]=(P){0,n,0};
rep(i,1,n){
if (st<=ed && i>q[st].r) st++;
f[i]=cal(q[st].p,i);
if (st>ed || cal(i,n)<=cal(q[ed].p,n)){
while (st<=ed && cal(i,q[ed].l)<=cal(q[ed].p,q[ed].l)) ed--;
if (st>ed) q[++ed]=(P){i,n,i};
else{
int t=find(q[ed],i);
q[ed].r=t-1; q[++ed]=(P){t,n,i};
}
}
}
}

int main(){
freopen("bzoj1563.in","r",stdin);
freopen("bzoj1563.out","w",stdout);
for (scanf("%d",&T); T--; ){
scanf("%d%d%d",&n,&l,&p);
rep(i,1,n) scanf("%s",ch[i]);
rep(i,1,n) sm[i]=sm[i-1]+strlen(ch[i]);
DP();
if (f
>MAX) printf("Too hard to arrange\n");
else printf("%lld\n",(long long)(f
));
puts("--------------------");
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: