• NOIP模拟题——Landscaping


    2. Landscaping
    题目描述
    N(1 <= N <= 100)个数排成一行,值分别为A_i,现在希望把每个数对应地改成B_i。(A_i,B_i的值均在0..10之间)。改变的方式有3种:
    (1)把A_i增加到B_i,每增加1,花费$X
    (2)把A_i减少到B_i,每减少1,花费$Y
    (3)把第i个数的值转移到第j个数,每转移1,花费为$Z*|i-j|
    问:最小的花费是多少。
    输入
    第1行:4个整数 N, X, Y, Z (0 <= X, Y, Z <= 1000).
    第2..1+N行: 每行2个整数 A_i 和 B_i.
    输出
    第1行:1个整数,表示最小的花费。
    样例输入
    4 100 200 1
    1 4
    2 3
    3 2
    4 0
    样例输出
    210
    提示
    INPUT DETAILS: There are 4 flowerbeds in a row, initially with 1, 2, 3, and 4 units of dirt. Farmer John wishes to transform them so they have 4, 3, 2, and 0 units of dirt, respectively. The costs for adding, removing, and transporting dirt are 100, 200, and 1.
    OUTPUT DETAILS: One unit of dirt must be removed (from flowerbed #4), at a cost of 200. The remaining dirt can be moved at a cost of 10 (3 units from flowerbed #4 to flowerbed #1, 1 unit from flowerbed #3 to flowerbed #2).
    ***********************************************************************

    由于加或减不一定要加完,可以将每个数拆分成几个代表单位1的数(保存编号)。

    考虑DP。F[I][J]表示A数组的I状态和B数组的J状态要相等的话,最小的花费。

    由于拆成单位1,所以状态转移方程:

    f[i][j]=min(f[i][j],f[i-1][j]+Y);//增加X
    f[i][j]=min(f[i][j],f[i][j-1]+X);//增加y等价于降低x
    f[i][j]=min(f[i][j],f[i-1][j-1]+abs(a[i]-b[j])*Z);

    初值:当I状态为0时,要变成j状态只能都加X;当J状态为0时,要变成I状态只能都加X(即A数组减Y)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 const int maxn=1005;
     7 int a[maxn],b[maxn];
     8 int temp1,temp2;
     9 int f[maxn][maxn];
    10 int n,X,Y,Z;
    11 inline int abs(int x)
    12 {
    13     if(x<0)return -x;
    14     return x;
    15 }
    16 int main()
    17 {
    18     freopen("landscaping.in","r",stdin);
    19     freopen("landscaping.out","w",stdout);
    20     scanf("%d%d%d%d",&n,&X,&Y,&Z);
    21     for(int i=1;i<=n;i++)
    22     {
    23         int x,y;
    24         scanf("%d",&x);
    25         while(x)
    26         {
    27             a[++temp1]=i;
    28             x--;
    29         }
    30         scanf("%d",&y);
    31         while(y)
    32         {
    33             b[++temp2]=i;
    34             y--;
    35         }
    36     }
    37     for(int i=1;i<=temp1;i++)//增加y等价于降低x 
    38     f[i][0]=Y*i;
    39     for(int j=1;j<=temp2;j++)
    40     f[0][j]=X*j;//增加x
    41     for(int i=1;i<=temp1;i++)
    42     for(int j=1;j<=temp2;j++)
    43     {
    44         f[i][j]=1e8;
    45         f[i][j]=min(f[i][j],f[i-1][j]+Y);//增加X
    46         f[i][j]=min(f[i][j],f[i][j-1]+X);//增加y等价于降低x
    47         f[i][j]=min(f[i][j],f[i-1][j-1]+abs(a[i]-b[j])*Z);
    48     }
    49     printf("%d",f[temp1][temp2]);
    50     return 0; 
    51 }
  • 相关阅读:
    Oracle 数据库(oracle Database)Select 多表关联查询方式
    Mysql下在某一列后即表的某一位置添加新列的sql语句
    通过javascript库JQuery实现页面跳转功能代码
    Linux 流量监控软件 NetHogs
    php和mysql中uft8中文编码乱码的几种解决办法
    Codeigniter 2.0多目录配置详解
    PHP编程54条必知
    Ubuntu 安装XAMPP集成环境软件包 与 运行WordPress 的简单方法
    Ubuntu 12.04 lts / Win7双系统安装方法
    smarty的配置使用
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/6054731.html
Copyright © 2020-2023  润新知