zoukankan      html  css  js  c++  java
  • [NOI2009]诗人小G 四边形优化DP

    题目传送门

    f[i] = min(f[j] + val(i,j);

    其中val(i,j) 满足 四边形dp策略。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    char s[N][55];
    int sum[N];
    int ans[N];
    long double f[N];
    struct Node{
        int j, l, r;
    }q[N];
    int n, l, p;
    LL maxxx = 1e18;
    long double val(int i, int j){
        if(i > j) swap(i,j);
        long double tt = abs(sum[j]-sum[i]+j-i-1-l);
        long double zz = 1;
        for(int i = 1; i <= p; ++i){
            zz *= tt;
        }
        zz += f[i];
        return zz;
    }
    void solve(int n){
        if(n == 0) return ;
        solve(ans[n]);
        for(int i = ans[n]+1; i <= n; ++i){
            printf("%s%c",s[i]," 
    "[i==n]);
        }
    }
    int main(){
    //    cout << (702871197447575ll<1e18) << endl;
        int T;
        scanf("%d", &T);
        for(int _ = 1; _ <= T; ++_){
            scanf("%d%d%d", &n, &l, &p);
            for(int i = 1; i <= n; ++i){
                scanf("%s", s[i]);
                sum[i] = sum[i-1] + strlen(s[i]);
            }
            int L = 1, R = 1;
            q[L] = {0,1,n};
            int midl;
            for(int i = 1; i <= n; ++i){
                q[L].l = i;
                while(L <= R && q[L].r < i) ++L;
                ans[i] = q[L].j;
                f[i] =  val(q[L].j,i);
                midl = n+1;
                while(L <= R && val(q[R].j, q[R].l) >= val(i, q[R].l)){
                    R--;
                }
                if(L <= R){
                    int ll = q[R].l, rr = q[R].r;
                    while(ll <= rr){
                        int mid = (ll+rr) >> 1;
                        if(val(q[R].j,mid) < val(i, mid)) ll = mid+1;
                        else rr = mid - 1;
                    }
                    if(ll <= n){
                        q[R].r = ll-1;
                        q[++R] = {i,ll,n};
                    }
                }
                else {
                    q[++R] = {i,i+1,n};
                }
            }
            if(f[n] > maxxx)
                puts("Too hard to arrange");
            else{
                LL fans = f[n];
                printf("%lld
    ", fans);
                solve(n);
            }
            puts("--------------------");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【云速建站】购买前的指导
    【云速建站】域名配置指导
    Python爬虫批量下载糗事百科段子,怀念的天王盖地虎,小鸡炖蘑菇...
    舌尖上的安全
    【云速建站】视频播放专题
    Python装饰器总结,带你几步跨越此坑!
    让你提前认识软件开发(15):程序调试的利器—日志
    Win8下IIS的安装和站点的公布
    [2011山东ACM省赛] Mathman Bank(模拟题)
    Android UI开发神兵利器之Android Action Bar Style Generator
  • 原文地址:https://www.cnblogs.com/MingSD/p/10093840.html
Copyright © 2011-2022 走看看