算法设计与分析 实验七 线性规划

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

入:第一行为两个数 n,m,分别表示序列长度及区间个数。第二行有 n 个数,描述序列 C (Ci≤10000)

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

出:一个整数,代表最少花费

入:5 3   1 5 6 3 4    2 3 1     1 5 4    3 5 2
出:11

#include
#include
#include
#include
using namespace std;
int n, m; double shuzu1[1005][10005];double temp1 = 1e-6, temp2 = 2e9;
void hanshu1(int a, int b) {
	int i, j, x=0;
	int p[10001];
	double t = shuzu1[a][b];
	shuzu1[a][b] = 1.0;
	
	for (i = 0; i <= n; i++)
		if (fabs(shuzu1[a][i]) > temp1) {
			shuzu1[a][i] =shuzu1[a][i] / t;
			x++;
			p[x] = i;
		}
	for (i = 0; i <= m; i++)
		if (i != a && fabs(shuzu1[i][b]) > temp1) {
			t = shuzu1[i][b];
			shuzu1[i][b] = 0;
			for (j = 1; j <= x; j++){
				shuzu1[i][p[j]] -= t * shuzu1[a][p[j]];
			}
		}
}
void hanshu2() {
	int i;
	while (1) {
		int x = 0, y = 0;
		for (i = 1; i <= n; i++)
			if (shuzu1[0][i] > temp1) {
				x = i;
				break;
			}
		if (x == 0) return;
		double tmp = temp2;
		for (i = 1; i <= m; i++) {
			if (shuzu1[i][x] > temp1 && shuzu1[i][0] / shuzu1[i][x] < tmp) {
				tmp = shuzu1[i][0] / shuzu1[i][x];
				y = i;
			}
		}
		hanshu1(y, x);
	}
}
int main() {
	int i, j;
	int a, b, c;
	cin >> m >> n;
	for (i = 1; i <= m; i++){
		scanf("%lf", &shuzu1[i][0]);
	}
	for (i = 1; i <= n; i++) {
		cin >> a >> b >> c;
		shuzu1[0][i] = c;
		for (j = a; j <= b; j++) {
			shuzu1[j][i] = 1;
		}
	}
	hanshu2();
	int xx = (int)(-shuzu1[0][0] + 0.5);
	cout << xx << endl;
}

2.志愿者招聘:经过估算,这个项目需要 n 天才能完成,其中第 i 天至少需要 ai 个志愿者。布布通过了解得知,一共有 m 类志愿者可以抬募。其中第 i 类可以从第 si 天工作到 ti 天,招募费用是每人 ci 元。布布希望用尽量少的费用招足够多的志愿者,请你帮他设计一种最优的招募方案。

入:第一行包含两个整数 n,m, 表示完成项目的天数和可以招募的志愿者的种类数。

接下来的一行中包含 n 个非负整数,表示各天至少需要的志愿者人数。

接下来的 m 行中每行包含三个整数 si,ti,ci, 含义如上文所述。为了方便起见,我们可以认为每类志愿者的数量都是无限多的,同时保证一定存在最优方案。

出:仅包含一个整数,表示你所设计的最优方案的总费用。
入:3 3    2 3 4    1 2 2    2 3 5     3 3 2
出:14

#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int temp1=0x3f;const int maxn=1005; const LL MAX=0x3f3f3f3f3f3f3f3f;
class point{
public:
	LL ax,bx,cx,dx,ex;
};
point po[maxn<<5];
int head[maxn];
int a,x,y,kk=1;
void hanshu1(LL a,LL b, LL c, LL d){
	po[kk].ax=b;
	po[kk].bx=c; po[kk].cx=d; po[kk].dx=head[a];
	po[kk].ex=kk+1;  head[a]=kk++; po[kk].ax=a; po[kk].bx=0; 
po[kk].cx=-d;po[kk].dx=head[b];po[kk].ex=kk-1; head[b]=kk++;}
LL dis[maxn<<1],ow[maxn<<1],h[maxn<<1];
bool vis[maxn<<1];int pre[maxn<<1],ff[maxn<<1];
bool hanshu2(int a, int b){
	memset(vis,false,sizeof(vis));memset(dis, temp1, sizeof(dis));              memset(ow, temp1, sizeof(ow)); 
	priority_queue > dd;
	dis[a] = 0;
	dd.push(make_pair(-dis[a], a) );                  
	while(!dd.empty() ){
		int u = dd.top().second;
		dd.pop();
		if(vis[u]){
			continue; 
		}                          
		vis[u] = true;
		for(int i=head[u]; i; i=po[i].dx){
			point &e = po[i];
			if(vis[e.ax]){
				continue;
			}
			if(e.bx>0 && dis[e.ax] > dis[u] + e.cx + h[u] - h[e.ax]){
				dis[e.ax] = dis[u] + e.cx + h[u] - h[e.ax];
				pre[e.ax] = u;                             
				ff[e.ax] = i;                         
				ow[e.ax] = min(ow[u], e.bx); 
				dd.push(make_pair(-dis[e.ax], e.ax));     
			}
		} 
	}	   
	for(int i=1;i<=b;i++){
		h[i] += dis[i];
	}                    
	return dis[b] != MAX;                              
} 
void hanshu3(){
	LL flowmax = 0,costmin = 0; 
	while(hanshu2(x, y)){                                 
		flowmax += ow[y];
		costmin += ow[y] * h[y];                    
		int now = y;
		while(now!=x){                                   
			point &e = po[ff[now]]; 
			e.bx -= ow[y];                              
			po[e.ex].bx += ow[y];
			now = pre[now];
		}
	}
	printf("%lld\n",costmin);
} 
int main(){
	int n,m;
	cin>>n>>m;
	x=n+2;  y=n+3;
	for(int i=1;i<=n;i++){
		cin>>a;
		hanshu1(i,i+1,MAX-a,0);
	} 
	hanshu1(x,1,MAX,0);
	hanshu1(n+1,y,MAX,0);
	int s,t;
	for(int i=1;i<=m;i++){
		cin>>s>>t>>a;
		hanshu1(s,t+1,MAX,a);
	}
	hanshu3(); 
}

你可能感兴趣的:(算法,算法,c++)