zoukankan      html  css  js  c++  java
  • BZOJ1563 NOI2009诗人小G(动态规划+决策单调性)

      设f[i]为前i行的最小不协调度,转移枚举这一行从哪开始,显然有f[i]=min{f[j]+abs(s[i]-s[j]+i-j-1-m)p}。大胆猜想有决策单调性就好了。证明看起来很麻烦,从略。注意需要全程long double。

    #include<bits/stdc++.h>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f; 
    }
    #define N 100010
    #define inf 1000000000000000001ll
    #define ll long long
    #define ld long double
    int T,n,m,p,a[N],from[N],stk[N],L[N],R[N],top;
    ld f[N];
    char s[N][32];
    void print(int n)
    {
        if (n==0) return;
        print(from[n]);
        for (int i=from[n]+1;i<n;i++) printf("%s ",s[i]);
        puts(s[n]);
    }
    ld ksm(ld a,int k)
    {
        ld s=1;
        for (;k;k>>=1,a*=a) if (k&1) s*=a;
        return s;
    }
    ld calc(int i,int j){return f[j]+ksm(abs(a[i]-a[j]-m),p);}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            n=read(),m=read()+1,p=read();
            for (int i=1;i<=n;i++) scanf("%s",s[i]),a[i]=a[i-1]+strlen(s[i]);
            for (int i=1;i<=n;i++) f[i]=inf,a[i]+=i;
            stk[top=1]=0;L[1]=1,R[1]=n;
            for (int i=1;i<=n;i++)
            {
                int l=1,r=top;
                while (l<=r)
                {
                    int mid=l+r>>1;
                    if (R[mid]>=i) from[i]=stk[mid],r=mid-1;
                    else l=mid+1;
                }
                f[i]=calc(i,from[i]);
                while (L[top]>i&&calc(L[top],i)<calc(L[top],stk[top])) top--;
                l=max(L[top],i+1),r=R[top];int x=R[top]+1;
                while (l<=r)
                {
                    int mid=l+r>>1;
                    if (calc(mid,i)<calc(mid,stk[top])) x=mid,r=mid-1;
                    else l=mid+1;
                }
                R[top]=x-1;if (x<=n) stk[++top]=i,L[top]=x,R[top]=n;
            }
            if (f[n]<inf) printf(LL,(ll)f[n]),print(n);
            else puts("Too hard to arrange");
            for (int i=1;i<=20;i++) putchar('-');if (T) printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    ES6中的基础语法
    let和const、var
    iframe框架
    ajax
    面试题
    移动端的点击延迟事件
    移动端如何设置字体
    swiper插件以及简介
    第十二章 systemctl管理脚本
    第十一章 awk命令
  • 原文地址:https://www.cnblogs.com/Gloid/p/10272673.html
Copyright © 2011-2022 走看看