zoukankan      html  css  js  c++  java
  • HDU 4278 卡特兰,区间DP

    题意:每个人有一个DI值,现在有一个小黑屋,这些人的顺序可以利用这个小黑屋调整,调整方式是入栈出栈方式,也就是说,这里的方案是有卡特兰数个方式。

    调整后使得 d1*0 + d2*1 + d3*2 + d4*3 ...... 最小。

    分析:这个题目竟然会是区间DP。

    考虑区间 [ L, R ] ,那么L,可以从任意位置出栈,枚举出栈位置,可以划分为两个部分,也就是说两个子问题,但是如何利用这两个子问题得到 d[L,R],

    d[L,R] = 前一部分 + D[L]*(i-L) + 后一部分 + 后一部分进位。

    其中,后一部分的进位是一个前缀和*进多少位。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 105;
    const int inf = 0x3f3f3f3f;
    
    int a[maxn];
    int d[maxn][maxn];
    int su[maxn];
    
    int dp(int L,int R) {
        if(L>=R) return 0;
        if(d[L][R]!=-1) return d[L][R];
        d[L][R] = inf;
        for(int i=L;i<=R;i++) {
            d[L][R] = min(d[L][R], dp(L+1, i)+(i-L)*a[L]+dp(i+1, R)+(su[R]-su[i])*(i+1-L));
        }
        return d[L][R];
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t;
        scanf("%d",&t);
        int kase = 1;
        while(t--) {
            int n;
            scanf("%d",&n);
    
            memset(d,-1,sizeof(d));
            memset(su,0,sizeof(su));
    
            for(int i=1;i<=n;i++) {
                scanf("%d",&a[i]);
                su[i] = su[i-1] + a[i];     //前缀和
            }
    
            printf("Case #%d: %d
    ",kase++,dp(1,n));
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ASP.NET应用程序与页面生命周期
    阻塞分析
    性能和异常日志
    solr 搜索引擎及搜索推荐应用
    solr 搜索引擎
    分布式缓存地址
    Windows平台分布式架构实践
    职责链模式vs状态模式区别
    HBase
    单例模式
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7210252.html
Copyright © 2011-2022 走看看