• You Are the One


    题意:

    有n个人排队,第i个入场的人x的不愉快度是$D_x*(i-1)$,现在给你n个人在队伍中的位置,

    你可以用一个栈让一个人后面的人先进入,问最小的不愉快度是多少。

    解法:

    考虑注意到用栈调整次序时,如果$x_1$从$l$调整到了$r$的位置,那么如果有$x_2$的位置在$l$,

    $r$之间那么一定要满足$l<l_2<=r_2<r$。

    这样考虑dp:

    $f(i,j)$表示i到j最大可以通过调整减小多少的不愉快度,这样就可以dp了。

    (注意在转移不交换的情况下$f(i,j) = max { f(i+1,j), f(i,j-1) }$ 不正确,

    因为这样求出来的是一个一个大区间套着小区间的答案,不能表示两个区间相互独立的情况,

    应该是$f(i,j) = max { f(i,k)+f(k+1,j) }$)

    时间复杂度$O(n^3)$。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 #define N 110
     6 
     7 using namespace std;
     8 
     9 int n,ans;
    10 int D[N],f[N][N],S[N];
    11 
    12 int main()
    13 {
    14     int T,Te=0;
    15     scanf("%d",&T);
    16     while(T--)
    17     {
    18         scanf("%d",&n);
    19         S[0]=0;
    20         ans=0;
    21         for(int i=1;i<=n;i++)
    22         {
    23             scanf("%d",&D[i]);
    24             S[i]=S[i-1]+D[i];
    25             ans+=(i-1)*D[i];
    26         }
    27         for(int i=1;i<=n;i++) f[i][i]=0;
    28         for(int d=2;d<=n;d++)
    29         {
    30             for(int i=1;i<=n-d+1;i++)
    31             {
    32                 int j=i+d-1;
    33                 f[i][j]=0;
    34                 for(int k=i;k<j;k++)
    35                     f[i][j] = max(f[i][j], f[i][k]+f[k+1][j]);
    36                 f[i][j] = max(f[i][j], f[i+1][j]+S[j]-S[i]-D[i]*(j-i));
    37             }
    38         }
    39         printf("Case #%d: %d
    ",++Te,ans-f[1][n]);
    40     }
    41     return 0;
    42 }
    View Code
  • 相关阅读:
    关于LINUX文件与目录的问题说明
    poj1094拓扑排序
    poj3026(bfs+prim)最小生成树
    快速幂
    hdu4255筛素数+广搜
    网易2012校园招聘笔试题目
    网新恒天2011.9.21招聘会笔试题
    HDU3344(小广搜+小暴力
    HDU3348(贪心求硬币数
    HDU3345广搜 (P,E,T,#)
  • 原文地址:https://www.cnblogs.com/lawyer/p/6534332.html
Copyright © 2020-2023  润新知