• HDU 5550


    链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5550

    题意:

    一个大楼有n(2≤n≤4000)层,每层可以建一个乒乓球房或者一个游泳房,且每种房间在大楼里至少要有一个。
    已知每层有ti个乒乓球运动员和pi个游泳运动员(1≤ti,pi≤1e9)。
    问怎样建房,才能使得所有运动员到相应房间的总距离最小,输出最小值。

    分析:

    因为每种房间在大楼里至少要有一个,所以肯定会有这样一种状态:第i层是一种房间,第i+1层是另一种房间。
    所以可以设d[i][x]:第i层是x房间,且第i+1层是另一种房间时,前i层的最优解。
    则状态转移方程为:d[i][x] = min(d[k][x^1] + 第k+1~i层都是x房间时所产生的最小总距离),1≤k<i。
    其中x^1表示另一种房间,求第L~R层都是x房间时所产生的最小总距离可以用前缀和预处理,具体看代码。
    BTW,此题为2015年CCPC的银牌题。

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 typedef long long int LLI;
     6 const LLI INF = 0x3f3f3f3f3f3f3f3f;
     7 const int UP = 4000 + 5;
     8 LLI sum[UP][2]; // sum[i][x]:前i层x运动员的总人数
     9 LLI dist[UP][2]; // dist[i][x]:前i层所有x运动员到第0层的总距离
    10 LLI d[UP][2]; // d[i][x]:第i层是x房间,且第i+1层是另一种房间时,前i层的最优解
    11 
    12 LLI toLeft(int L, int R, int x) { // 第L~R层的所有x运动员到第L-1层的总距离
    13     return (dist[R][x]-dist[L-1][x]) - (sum[R][x]-sum[L-1][x]) * (L-1);
    14 }
    15 
    16 LLI toRight(int L, int R, int x) { // 第L~R层的所有x运动员到第R+1层的总距离
    17     return (sum[R][x]-sum[L-1][x]) * (R+1) - (dist[R][x]-dist[L-1][x]);
    18 }
    19 
    20 LLI process(int L, int R, int x) { // 第L~R层的所有x运动员到第L-1层或R+1层的总距离最小值
    21     int M = L + (R-L)/2;
    22     return toLeft(L, M, x) + (M+1>R ? 0 : toRight(M+1, R, x));
    23 }
    24 
    25 int main() {
    26     int T, n;
    27     LLI t, p;
    28     scanf("%d", &T);
    29     for(int cases = 1; cases <= T; cases++) {
    30         scanf("%d", &n);
    31         for(int i = 1; i <= n; i++) {
    32             scanf("%lld%lld", &t, &p);
    33             sum[i][0] = sum[i-1][0] + t;
    34             sum[i][1] = sum[i-1][1] + p;
    35             dist[i][0] = dist[i-1][0] + t*i;
    36             dist[i][1] = dist[i-1][1] + p*i;
    37         }
    38         LLI ans = INF;
    39         for(int i = 1; i < n; i++) {
    40             d[i][0] = toRight(1, i, 1); // 前i层都是0房间,第i+1层是1房间的总距离
    41             d[i][1] = toRight(1, i, 0); // 前i层都是1房间,第i+1层是0房间的总距离
    42             for(int k = 1; k < i; k++) {
    43                 d[i][0] = min(d[i][0], d[k][1] + process(k+1,i,1)); // 第k+1~i层都是0房间
    44                 d[i][1] = min(d[i][1], d[k][0] + process(k+1,i,0)); // 第k+1~i层都是1房间
    45             }
    46             ans = min(ans, d[i][0] + toLeft(i+1,n,0)); // 后i+1层都是1房间
    47             ans = min(ans, d[i][1] + toLeft(i+1,n,1)); // 后i+1层都是0房间
    48         }
    49         printf("Case #%d: %lld
    ", cases, ans);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    ios原生项目内嵌u3d工程
    u3d内嵌H5游戏 设置cookie
    unity3d IL2CPP for android
    unity3D内嵌android项目
    Django 跨域问题
    tensorflow 调试tfdbg
    Cuda9.1+cunn7.1+Tensorflow1.7-GUP
    shader
    lua 中protobuf repeated 嵌套类 复合类型
    30岁的思考
  • 原文地址:https://www.cnblogs.com/hkxy125/p/9784927.html
Copyright © 2020-2023  润新知