zoukankan      html  css  js  c++  java
  • bzoj1563: [NOI2009]诗人小G 决策单调性(1D1D)


    目录

    题目链接

    bzoj1563: [NOI2009]诗人小G

    题解

    (n^2) 的dp长这样
    (f_i = min(f_j + (sum_i - sum_j - 1 - L)^P))
    (w_{ij} = (sum_i - sum_j - 1 - L)^P)
    那么化成1D1D的标准形式
    $ f_i = min(f_j + w_{i,j}) $
    发现w满足四边形不等式
    证明可以看这里
    https://www.byvoid.com/zhs/blog/noi-2009-poet
    因此状态转移方程具有单调性

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    #define gc getchar()
    #define pc putchar
    #define LD long double
    inline int read() {
        int x = 0,f = 1;
        char c = gc;
        while(c < '0' || c > '9' )c = gc;
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc;
        return x * f ;
    }
    void print(LL x) {
        if(x >= 10) print(x / 10);
        pc(x % 10 + '0');
    }
    const int maxn = 100007; 
    char s[maxn][32]; 
    int n,L,p; 
    inline LD fstpow(LD x,int k) { 
        LD ret = 1; 
        for(;k;k >>= 1,x = x * x) if(k & 1) ret *= x; 
        return ret; 
    } 
    LD f[maxn];
    int sum[maxn]; 
    LD calc(int j,int i) { 
        return f[j] + fstpow(std::abs(sum[i] - sum[j] - L),p); 
    } 
    int find(int x,int y) { 
        int l = x,r = n,ret = 0; 
        while(l <= r) { 
            int mid = l + r >> 1; 
            if(calc(x,mid) >= calc(y,mid)) r = mid - 1; 
            else l = mid + 1; 
        } 
        return l; 
    } 
    int q[maxn],c[maxn]; 
    int pre[maxn]; 
    void solve() { 
        n = read(),L = read() + 1,p = read(); 
        for(int i = 1;i <= n;++ i) { 
            scanf("%s",s[i] + 1); 
            sum[i] = sum[i - 1] + strlen(s[i] + 1) + 1; 
        } 
        int h = 1,t = 1; 
        q[h] = 0; 
        for(int i = 1;i <= n;++ i) { 
            while(h < t && c[h] <= i) ++ h;  
            f[i] = calc(q[h],i); pre[i] = q[h]; 
            while(h < t && c[t - 1] >= find(q[t],i)) t --; 
            c[t] = find(q[t],i); q[++ t] = i; 
        } 
        if(f[n] > 1e18) { 
            puts("Too hard to arrange
    --------------------"); 
            return;
        } 
        printf("%.0Lf
    ", f[n]); 
         
        puts("--------------------"); 
    } 
    int main() { 
        int T = read();
        for(int i = 1; i <= T; ++ i) {
            solve(); 
        } 
        return 0; 
    } 
    
  • 相关阅读:
    开启进程
    操作系统
    多线程(进程)目录
    网络编程-基于UDP协议套接字
    网络编程-文件传输
    EXt js 学习笔记总结
    Sencha Toucha 2.1 文件上传
    Sencha Touch 2.1学习图表Chart概述
    Sencha Touch 2.1 Chart属性中文解释
    Ext.Ajax.request方法 参数
  • 原文地址:https://www.cnblogs.com/sssy/p/9769378.html
Copyright © 2011-2022 走看看