zoukankan      html  css  js  c++  java
  • BZOJ3112 [ZJOI2013]防守战线

    Description

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

    Input

    第一行为两个数n,m。
    接下来一行,有 n个数,描述 C数组。
    接下来 m行,每行三个数 Li,Ri,Di,描述一个区间。

    Output

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

    Sample Input

    5 3
    1 5 6 3 4
    2 3 1
    1 5 4
    3 5 2

    Sample Output

    11

    Hint

    样例提示:
    位置 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。

    Source

    ZJOI2013
    网络流, 线性规划,单纯形

    正解:线性规划单纯形

    解题报告:这种鬼东西我说不了太多,蒟蒻我只会模板
     
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #define RG register
    const double eps = 1e-9;
    const double inf = 1e20;
    
    using namespace std;
    
    int gi(){
    	char ch=getchar();int x=0;
    	while(ch<'0' || ch>'9') ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x;
    }
    
    int n,m;
    double a[1050][10050];
    int b[10050];
    
    void pivot(int l,int e){
    	double k=a[l][e];a[l][e]=1;
    	for (RG int i=0; i<=n; ++i) a[l][i]/=k;
    	int len=0;
    	for (RG int i=0; i<=n; ++i) if (fabs(a[l][i])>eps) b[++len]=i;
    	for (RG int i=0; i<=m; ++i)
    		if (i!=l && fabs(a[i][e])>eps){
    			k=a[i][e];a[i][e]=0;
    			for (RG int j=1; j<=len; ++j) a[i][b[j]]-=k*a[l][b[j]];
    		}
    }
    
    double simplex(){
    	while(1){
    		RG int l,e;
    		for (e=1; e<=n; ++e) if (a[0][e]>eps) break;
    		if (e==n+1) return -a[0][0];
    		double tmp=inf;
    		for (RG int i=1; i<=m; ++i)
    			if (a[i][e]>eps && a[i][0]/a[i][e]<tmp) tmp=a[i][0]/a[i][e],l=i;
    		if (tmp==inf) return inf;
    		pivot(l,e);
    	}
    }
    
    int main(){
    	n=gi(),m=gi();
    	for (RG int i=1; i<=n; ++i) a[i][0]=gi();
    	for (RG int i=1; i<=m; ++i){
    		int l=gi(),r=gi();
    		for (RG int j=l; j<=r; ++j) a[j][i]=1;
    		a[0][i]=gi();
    	}
    	swap(n,m);
    	printf("%lld",(long long)(floor(simplex()+0.5)));
    }
    
  • 相关阅读:
    c++ 中的substr
    c++ 中将数字字符串转换成int输出的stoi() 和 atoi()
    c++ 四舍五入函数 round
    stddef.h----常用函数
    local.h-----地区函数
    errno.h-----定义出错代码
    signal.h-----信号函数
    stdio.h----标准的输入输出函数
    time.h-------日期与时间函数
    math.h--------数学函数
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6545359.html
Copyright © 2011-2022 走看看