• [ZJOI2013]防守战线


    题目描述

    战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算。有m 个区间[L1, R1], [L2, R2], …, [Lm, Rm],在第i 个区间的范围内要建至少Di 座塔。求最少花费。

    输入输出格式

    输入格式:

    第一行为两个数n, m。

    接下来一行,有n 个数,描述C 数组。

    接下来m 行,每行三个数Li,Ri,Di,描述一个区间。

    输出格式:

    仅包含一行,一个数,为最少花费。

    输入输出样例

    输入样例#1: 复制
    5 3
    1 5 6 3 4
    2 3 1
    1 5 4
    3 5 2
    输出样例#1: 复制
    11

    说明

    【样例说明】

    位置1 建2 个塔,位置3 建一个塔,位置4 建一个塔。花费1*2+6+3=11。

    【数据规模】

    对于20%的数据,n≤20,m≤20。

    对于50%的数据(包括上部分的数据),Di 全部为1。

    对于70%的数据(包括上部分的数据),n≤100,m≤1000。

    对于100%的数据,n≤1000,m≤10000,1≤Li≤Ri≤n,其余数据均≤10000。

    这个是求线性规划的最小值

    可以转化为它的对偶问题,答案是一样的

    把原矩阵转置,然后单纯型法

    还不需要判断无解和辅助变量

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 double a[1001][10001],eps=1e-8,inf=2e15;
     8 int n,m;
     9 void pivot(int l,int e)
    10 {int i,j;
    11   double t=a[l][e];
    12   a[l][e]=1.0;
    13   int arr[10001],tot=0;
    14   for (i=0;i<=n;i++)
    15     if (fabs(a[l][i])>eps)
    16       {
    17       a[l][i]/=t;
    18       tot++;
    19       arr[tot]=i;
    20       }
    21   for (i=0;i<=m;i++)
    22     if (i!=l&&fabs(a[i][e])>eps)
    23       {
    24       t=a[i][e];a[i][e]=0;
    25       for (j=1;j<=tot;j++)
    26         a[i][arr[j]]-=t*a[l][arr[j]];
    27       }
    28 }
    29 void simplex()
    30 {int i;
    31   while (1)
    32     {
    33       int x=0,y=0;
    34       for (i=1;i<=n;i++)
    35       if (a[0][i]>eps)
    36         {x=i;break;}
    37        if (x==0) return;
    38       double tmp=inf;
    39       for (i=1;i<=m;i++)
    40       {
    41         if (a[i][x]>eps&&a[i][0]/a[i][x]<tmp)
    42           {
    43             tmp=a[i][0]/a[i][x];
    44             y=i;
    45           }
    46       }
    47       pivot(y,x);
    48     }
    49 }
    50 int main()
    51 {int i,j,u,v,d;
    52   cin>>m>>n;
    53   for (i=1;i<=m;i++)
    54     scanf("%lf",&a[i][0]);
    55   for (i=1;i<=n;i++)
    56     {
    57       scanf("%d%d%d",&u,&v,&d);
    58       a[0][i]=d;
    59       for (j=u;j<=v;j++)
    60       a[j][i]=1;
    61     }
    62   simplex();
    63   printf("%d
    ",(int)(-a[0][0]+0.5));
    64 }
  • 相关阅读:
    2017年第八届蓝桥杯C/C++ C组国赛 —— 第一题:哥德巴赫分解
    Tree Walk Aizu
    Tree Walk Aizu
    Binary Trees Aizu
    有效的括号
    划分整数
    最大子矩阵和
    最大子段和
    最长上升子序列
    合唱队形
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8456981.html
Copyright © 2020-2023  润新知