• HDU4283 You Are the One 区间DP


    该题题意为给定一个序列,这个序列能够按照栈的规则进行进出,只不过每个位置的数具有一个数值,每次用出来的顺序减1乘以这个数值,求最后的综合最小。

    我们有这样的设想,对于一个序列 A B C ... Z,他们有相对应的数值 value[A], value[B] ... value[Z],现在对整个串进行分析,我们试图分析能否找到该问题的子问题,设f[i][j] 为 i 到 j 这个序列能够出来的最小值,那么对于第i号元素来说,我们有如下选择,先出去若干个元素再让a出去,对于某一个区间,我们又可以细分下去。为什么要选择 i 号元素来考虑,因为我们考虑 i 号元素时,选择其他的元素段来考虑都将是一个连续的段落,这样就可以递归下去处理。

    还有一个问题就是当每次计算[a,b]时,我们都是单独的考虑这一段,也就是说如果a,a+1号元素出队的话,那么数值统计就是 (1-1) * value[a] + (2-1) * value[b]; 对于任意一段递归下去的区间都是这样计算,那么这样可能又会有疑问了,如何保持题中所说的顺序了,技巧就是当[a, b]前有 1,2...a-1 元素已经出队了,那么整个数值要加上 sum(value[a...b]) * (a-1)。可以去计算一下。

    代码如下:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <list>
    #include <set>
    #define INF 0x3f3f3f3f
    #define MAXN 100
    using namespace std;
    
    int N, s[MAXN+5], f[MAXN+5][MAXN+5], seq[MAXN+5];
    
    int dfs(int x, int y) {
        if (f[x][y] != INF) {
            return f[x][y];    
        } else if (x >= y) return 0;
        for (int i = 0; i <= y-x ; ++i) {
            f[x][y] = min(f[x][y], dfs(x+1, x+i) + dfs(x+i+1, y) + (i+1)*(s[y]-s[x+i]) + i*seq[x]);
        }
        return f[x][y];
    }
    
    int main() {
        int T, ca = 0;
        scanf("%d", &T);
        while (T--) {
            memset(f, 0x3f, sizeof (f));
            scanf("%d", &N);
            for (int i = 1; i <= N; ++i) {
                scanf("%d", seq+i);
                s[i] = s[i-1] + seq[i];
            }
            printf("Case #%d: %d\n", ++ca, dfs(1, N));
        }
        return 0;
    }
  • 相关阅读:
    来自lombok的注解(解决idea中的找不到get,set方法,找不到log的问题)
    IDL语言开发规范
    神经网络训练时出现nan错误
    Hadoop WordCount程序
    Hadoop2.4.1伪分布式安装
    Hadoop简介
    linux 安装tensorflow(gpu版本)
    高级映射,查询缓存和与spring整合
    用mybatis实现dao的编写或者实现mapper代理
    mybatis介绍与环境搭建
  • 原文地址:https://www.cnblogs.com/Lyush/p/2679273.html
Copyright © 2020-2023  润新知