1. 程式人生 > >[NOI2008]志願者招募,洛谷P3980,線性規劃對偶定理以及整數解

[NOI2008]志願者招募,洛谷P3980,線性規劃對偶定理以及整數解

正題

      題目連結

      這一題很容易構造一個線性規劃的模型。

      對於每一天,在這一天的志願者的總和大於等於需要的人數,最小化每種志願者乘其單價費用的和。

      它的對偶問題也很容易構造出來。

      再來看對偶之後的A矩陣,一定是一個01矩陣,並且需要的人數和單價都為整數,那麼就符合整數解的條件。

      連構造初始解都不用,直接上單純形。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;

int n,m;
double a[10010][1010];
double eps=1e-5;

int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0' || ch>'9') ch=getchar();
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}

void pivot(int x,int y){
	double temp=a[x][y];a[x][y]=1;
	for(int i=0;i<=n;i++) a[x][i]/=temp;
	for(int i=0;i<=m;i++) if(x!=i){
		temp=a[i][y];a[i][y]=0;
		for(int j=0;j<=n;j++) a[i][j]-=temp*a[x][j];
	}
}

void simplex(){
	int x,y;
	double mmin;
	while(1){
		x=y=0;
		for(int i=1;i<=n;i++) if(a[0][i]>eps) {y=i;break;}
		if(y==0) break;
		mmin=(double)1e15;
		for(int i=1;i<=m;i++) if(a[i][y]>eps && a[i][0]/a[i][y]<mmin) mmin=a[i][0]/a[i][y],x=i;
		if(x==0) break;
		pivot(x,y);
	}
}

int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++) a[0][i]=read();
	int x,y,c;
	for(int i=1;i<=m;i++){
		x=read();y=read();c=read();
		a[i][0]=c;
		for(int j=x;j<=y;j++) a[i][j]=1;
	}
	simplex();
	printf("%.0lf",-a[0][0]);
}