• You Are the One HDU


    Problem Description
      The TV shows such as You Are the One has been very popular. In order to meet the need of boys who are still single, TJUT hold the show itself. The show is hold in the Small hall, so it attract a lot of boys and girls. Now there are n boys enrolling in. At the beginning, the n boys stand in a row and go to the stage one by one. However, the director suddenly knows that very boy has a value of diaosi D, if the boy is k-th one go to the stage, the unhappiness of him will be (k-1)*D, because he has to wait for (k-1) people. Luckily, there is a dark room in the Small hall, so the director can put the boy into the dark room temporarily and let the boys behind his go to stage before him. For the dark room is very narrow, the boy who first get into dark room has to leave last. The director wants to change the order of boys by the dark room, so the summary of unhappiness will be least. Can you help him?
    Input
      The first line contains a single integer T, the number of test cases.  For each case, the first line is n (0 < n <= 100)
      The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)
    Output
      For each test case, output the least summary of unhappiness .
    Sample Input
    2
     
    5
    1
    2
    3
    4
    5
     
    5
    5
    4
    3
    2
    2
    Sample Output
    Case #1: 20
    Case #2: 24
     
    题意给出 n 个人,每个人有一个 diaosi 值 D ,第 k 个人出场的 unhappy 值为 (k-1)*D ,现在导演有一个黑屋,可以像栈一样塞人放人,以此才改变出场顺序,求最小的 unhappy 值的和。
     
    (区间dp就是把一个大区间转换成两个小区间,我之前做的几题都是取中间的,然后分成左边和右边两个区间在做,然后这题我用这种想了一下,想不出来。)
     
    这里我们枚举 k 的时候,枚举 [i,j] 这个区间中第一个人 i 是第 k 个出场的。
    那么我们可以发现,对于 i,如果他是第 k 个出场的,那么一定是 i 到 i+k-1 以一种方式出场, 然后 i 出场,然后 i+k 到 j 以一种方式出场。这样我们分成了[i,i]、[i+1,i+k-1]、[i+k,j]这三个区间。
     
    那么 unhappy 值要如何计算呢。
    令 dp[i][j] 表示从 i 到 j 这些人以一种出场顺序的最小值。
    那么对于刚刚划分出来的三个区间 我们可以得到 dp[i][j] = dp[i+1][i+k-1] + (k-1)*a[i] + (sum[j]-sum[i+k-1])*k + dp[i+k][j]
    dp[i+1][i+k-1] :表示先出场这一批人的最小 unhappy 值
    (k-1)*a[i] :表示 i 出场时的unhappy值
    dp[i+k][j] :表示后面这一批人的最小 unhappy 值
    (sum[j]-sum[i+k-1])*k :表示后面这一批人需要额外加上的 unhappy 值
    /*
              .
             ';;;;;.
            '!;;;;;;!;`
           '!;|&#@|;;;;!:
          `;;!&####@|;;;;!:
         .;;;!&@$$%|!;;;;;;!'.`:::::'.
         '!;;;;;;;;!$@###&|;;|%!;!$|;;;;|&&;.
         :!;;;;!$@&%|;;;;;;;;;|!::!!:::;!$%;!$%`    '!%&#########@$!:.
         ;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
         ;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
        `!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
        :@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
        ;|::;;;;;;;;;;;;|&&$|;;!$@&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
       `!!;;;;;;;!!!!;;;;;$@@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
    %&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
    !%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
    ':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
     !@|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
      .:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
      .%$;;;;;;;;;;;;;;;;;;|$$$$@&|;;;;;;;;;;;;;;;;;;;;%@%.
        !&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
         `%$!;;;;;;;;;;;$@|;;;;;;;;;;;;;;;;;;;;;;;;!%$@#@|.
           .|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%$$$$$@#|.
               ;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
               |##$|!;;;;;;::'':;;;;;;;;;;;;;!%$$$@#@;
              ;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
            .%##@|;;;;:::''''''''''::;!%&##$'
          `$##@$$@@&|!!;;;:'''''::::;;;;;|&#%.
        ;&@##&$%!;;;;;;::''''''''::;!|%$@#@&@@:
         .%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
        :@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
         `%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
         |##&%!;;;;;::''''''''''''::;;;;;;;!$@&:`!'
        :;!@$|;;;;;;;::''''''''''':;;;;;;;;!%&@$:                 !@#$'
          |##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%:              '%%!%&;
          |&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||`            '%$|!%&;
          |@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&:           .|%;:!&%`
          !@&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$;          `%&%!!$&:
          '$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##;         !$!;:!$&:
           |#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%'      `%$|%%;|&$'
            |&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&;  .:%&$!;;;:!$@!
            `%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
            !&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
           '%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%$@@|'
           .!%%&%'`|$;       :|$#%|@#&;%#%.
    */
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pii        pair<int, int>
    #define  INOPEN     freopen("in.txt", "r", stdin)
    #define  OUTOPEN    freopen("out.txt", "w", stdout)
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 1e2 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    int a[maxn];
    ll dp[maxn][maxn], sum[maxn];
    
    int main() {
        cas = 1;
        scanf("%d", &T);
        while(T--) {
            sum[0] = 0;
            mes(dp, 0);
            scanf("%d", &n);
            for(int i=1; i<=n; i++) {
                for(int j=i+1; j<=n; j++) {
                    dp[i][j] = INF;
                }
            }
            for(int i=1; i<=n; i++) {
                scanf("%d", &a[i]);
                sum[i] = sum[i-1] + a[i];
            }
            for(int d=2; d<=n; d++) {
                for(int i=1, j=d; j<=n; i++, j++) {
                    for(int k=1; k<=j-i+1; k++) {
                        dp[i][j] = min(dp[i][j], dp[i+1][i+k-1]+dp[i+k][j]+(sum[j]-sum[i+k-1])*k+a[i]*(k-1));
                    }
    //                printf("dp[%d][%d] = %lld
    ", i, j, dp[i][j]);
                }
            }
            printf("Case #%d: %lld
    ", cas++, dp[1][n]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    AsEnumerable和AsQueryable的区别
    LinQ高级查询、组合查询、IQueryable集合类型
    减少该死的 if else 嵌套
    Linux中tomcat随服务器自启动的设置方法
    Linux虚拟机与主机网络连接配置与文件传输
    Linux + NodeJS 常用命令
    本地项目的npm安装方法
    npm 报错 : npm ERR! Maximum call stack size exceeded
    npm WARN checkPermissions Missing write access to ......解决方法
    webpack 安装使用简例
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/10398899.html
Copyright © 2020-2023  润新知