zoukankan      html  css  js  c++  java
  • 产品排序 product

        评测传送门

    【问题描述】
      你是一个公司的员工,你会按时间顺序受到一些产品的订单,你需要用一个栈来改变这些订单的顺序(每个产品都必须入栈和出栈一次)。
      按初始顺序,每次可以将一个产品入栈,或将栈顶产品弹至现在的序列末尾。

      每个产品有一个制作时间t i 和单位时间惩罚值d i 。

      总的惩罚值为∑ ni=1 (s i × d i ),其中s i 为第i个产品的完成时间,你需要最小化总的惩罚值。
    输入】
      输入文件 product.in。
      第一行一个数n,表示产品个数。
      接下来n行,每行两个数表示t i , d i 。
    输出】
      输出文件 product.out。
      一行一个数表示最小的总惩罚值。

    【样例输入】

      4

      1 4

      3 2

      5 2

      2 1

    【样例输出】

      40

    【数据范围】

      30%: n ≤ 15
      50%: n ≤ 100
      100%: n ≤ 200, t i , d i ≤ 1000

    正解:

      f[l][r] : 标号 l~r 的最小惩罚值 (时间上以开始生产[ l , r ]的产品为起始

      < st[ ] 为时间前缀和 sd[ ] 为单位时间惩罚值前缀和>

      在[l,r] 中枚举 i , i 为 [l,r]中最后一个出栈的元素 即栈中最后一个元素

      f[l][r]=min(f[l][r],f[l][i-1]+f[i+1][r]+(st[i-1]-st[l-1])*(sd[r]-sd[i])+(st[r]-st[l-1])*d[i]);

      这个转移方程式我真的想了差不多十分钟才看懂

      如下:(一定要仔细,耐心理解 qwq)

      i 为最后一个出栈的元素 所以 l ~ i-1 一定在 i 进栈前就出栈了(否则它们现在就还在栈中)

      f[l][i-1] 和 f[i+1][r] 都只与它们内部的顺序以及 [ l , i ]的总时间有关

      是两个互不相关的子问题

      (st[r]-st[l-1])*d[i]) 是 i 的惩罚值 很好理解

      (st[i-1]-st[l-1])*(sd[r]-sd[i]) 我觉得是一个很巧妙的地方啊

      我觉得我现在说不清楚 要自己领会一下qwq

      但是我还是要大概说一下<这里用记忆化搜索实现的>

          是加法结合律的逆向运用

          然后保证了计算f[i+1][r]的时间是包括[l,r]中比它们先出去的产品的完成时间的

          至于内部的顺序问题 又到下一层函数解决了

          层层递归

     CODE

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 #define LY(p) freopen (p".in", "r", stdin); freopen (p".out", "w", stdout)
     9 #define LL long long
    10 #define dbl double
    11 #define lf long double
    12 #ifdef WIN32
    13 #define L_L "%I64d"
    14 #else
    15 #define L_L "%lld"
    16 #endif
    17 #define N 210
    18 int n, t[N], d[N], st[N], sd[N];
    19 LL f[N][N];
    20 
    21 int main()
    22 {
    23     scanf ("%d", &n);
    24     for (int i = 1; i <= n; i++) {
    25         scanf ("%d %d", &t[i], &d[i]);
    26         st[i] = st[i - 1] + t[i];
    27         sd[i] = sd[i - 1] + d[i];
    28     }
    29 
    30     memset (f, 0x3f, sizeof (f));
    31     for (int i = 1; i <= n; i++)
    32         f[i][i] = d[i] * t[i], f[i][i - 1] = 0;
    33     f[n + 1][n] = 0;
    34 
    35     for (int l = 1; l < n; l++)
    36         for (int i = 1; i + l <= n; i++)
    37         {
    38             int j = i + l;
    39             for (int k = i; k <= j; k++)
    40                 f[i][j] = min
    41                     (f[i][k - 1] + f[k + 1][j] + 1LL * (st[k - 1] - st[i - 1]) * (sd[j] - sd[k]) + 1LL * (st[j] - st[i - 1]) * d[k], f[i][j]);
    42         }
    43 
    44     printf (L_L, f[1][n]);
    45     return 0;
    46 }
    std View Code 非记搜
     1 #include<iostream>
     2 #include<cstdio>
     3 #define go(i,a,b) for(register int i=a;i<=b;i++)
     4 #define ll long long
     5 #define M 201
     6 #define inf 21000000000000
     7 using namespace std;
     8 ll read()
     9 {
    10     int x=0,y=1;char c=getchar();
    11     while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
    12     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    13     return x*y;
    14 }
    15 ll n,t[M],d[M],st[M],sd[M],f[M][M];
    16 ll dfs(int l,int r)
    17 {
    18     if(l>r) return 0;
    19     if(l==r) return t[l]*d[l];
    20     if(f[l][r]) return f[l][r];
    21     f[l][r]=inf;
    22     go(i,l,r)
    23         f[l][r]=min(f[l][r],dfs(l,i-1)+dfs(i+1,r)+(st[r]-st[l-1])*d[i]+(st[i-1]-st[l-1])*(sd[r]-sd[i]));
    24     return f[l][r];
    25 }
    26 int main()
    27 {
    28     n=read();
    29     go(i,1,n)
    30     {
    31         t[i]=read();st[i]=st[i-1]+t[i];
    32         d[i]=read();sd[i]=sd[i-1]+d[i];
    33     }
    34     printf("%lld",dfs(1,n));
    35     return 0;
    36 }
    dtt View Code 记搜
    光伴随的阴影
  • 相关阅读:
    winform 剔除空格与换行显示
    编码
    todo
    react高阶函数组件
    Docker-compose Setup for Self-hosting Development & Deployment Tools
    Self-hosting Sentry With Docker and Docker-compose
    how does Array.prototype.slice.call() work?
    todo reading
    a better git log
    https://coderwall.com/p/7smjkq/multiple-ssh-keys-for-different-accounts-on-github-or-gitlab
  • 原文地址:https://www.cnblogs.com/forward777/p/10327827.html
Copyright © 2011-2022 走看看