• 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
  • 相关阅读:
    文字超出2行显示省略号
    js调试工具console方法详解
    下厨如有神
    画地为牢——广州经济困局
    数字桩和记忆术
    想象力提高记忆能力的重要能力
    三元色
    轻松自我介绍三步走——曼陀罗思考法
    英语单词_巩固方法草稿A
    http、TCP/IP协议与socket之间的区别
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7210252.html
Copyright © 2020-2023  润新知