1. 程式人生 > >BZOJ 3265 志願者招募加強版(單純形)

BZOJ 3265 志願者招募加強版(單純形)

3265: 志願者招募加強版

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 848  Solved: 436
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

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

Sample Output

14

HINT

題解:這一題類似於BZOJ1061,(幾乎相同,只是把一段連續區間改為幾段連續區間而已),做法一樣,單純形模板直接套就行; 具體看程式碼:   參考程式碼:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define cls(x, val) memset(x,val,sizeof(x))
 4 #define RI register int
 5 #define eps 1e-6
 6 typedef long long ll;
 7 typedef unsigned long long ull;
 8 const int INF=0x3f3f3f3f;
 9 inline int read()
10 {
11     int x=0,f=1;char
ch=getchar(); 12 while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 const int N=1005; 17 const int M=10005; 18 int n,m; 19 double a[M][N],b[M],c[M],v; 20 inline void pivot(int l,int e)//矩陣的轉秩
21 { 22 b[l]/=a[l][e]; 23 for(int j=1;j<=n;++j) 24 { 25 if(j!=e) a[l][j]/=a[l][e]; 26 } 27 a[l][e]=1/a[l][e]; 28 for(int i=1;i<=m;++i) 29 { 30 if(i!=l&&fabs(a[i][e])>0) 31 { 32 b[i]-=a[i][e]*b[l]; 33 for(int j=1;j<=n;++j) 34 { 35 if(j!=e) a[i][j]-=a[i][e]*a[l][j]; 36 } 37 a[i][e]=-a[i][e]*a[l][e]; 38 } 39 } 40 v+=c[e]*b[l]; 41 for(int j=1;j<=n;++j) 42 { 43 if(j!=e) c[j]-=c[e]*a[l][j]; 44 } 45 c[e]=-c[e]*a[l][e]; 46 } 47 48 inline double simplex() 49 { 50 while(1) 51 { 52 int e=0,l=0; 53 for(e=1;e<=n;++e) 54 { 55 if(c[e]>eps) break; 56 } 57 if(e==n+1) return v; 58 double mn=INF; 59 for(int i=1;i<=m;++i) 60 { 61 if(a[i][e]>eps&&mn>b[i]/a[i][e]) mn=b[i]/a[i][e],l=i; 62 } 63 if(mn==INF) return INF; 64 pivot(l,e); 65 } 66 } 67 68 int main() 69 { 70 n=read(),m=read(); 71 for(RI i=1;i<=n;++i) c[i]=read(); 72 for(RI i=1;i<=m;++i) 73 { 74 RI k=read(); 75 while(k--) 76 { 77 int s,t; 78 s=read(),t=read(); 79 for(RI j=s;j<=t;++j) a[i][j]=1.0; 80 } 81 b[i]=read(); 82 } 83 printf("%d\n",(int)(simplex()+0.5)); 84 return 0; 85 }
View Code