Description
申奧成功後,布布經過不懈努力,終於成爲奧組委下屬公司人力資源部門的主管。布布剛上任就遇到了一個難
題:爲即將啓動的奧運新項目招募一批短期志願者。經過估算,這個項目需要N 天才能完成,其中第i 天至少需要
Ai 個人。 布布通過了解得知,一共有M 類志願者可以招募。其中第i 類可以從第Si 天工作到第Ti 天,招募費用
是每人Ci 元。新官上任三把火,爲了出色地完成自己的工作,布布希望用盡量少的費用招募足夠的志願者,但這
並不是他的特長!於是布布找到了你,希望你幫他設計一種最優的招募方案。
Input
第一行包含兩個整數N, M,表示完成項目的天數和可以招募的志願者的種類。 接下來的一行中包含N 個非負
整數,表示每天至少需要的志願者人數。 接下來的M 行中每行包含三個整數Si, Ti, Ci,含義如上文所述。爲了
方便起見,我們可以認爲每類志願者的數量都是無限多的。
Output
Sample Input
3 3
2 3 4
1 2 2
2 3 5
3 3 2
Sample Output
14
HINT
1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,題目中其他所涉及的數據均 不超過2^31-1。
Source
代碼模板參考:http://blog.csdn.net/braketbn/article/details/50783719
這題可以用網絡流做 也可以用線性規劃做
講一講線性規劃單純性法:
對於以下式子
∑(j=1 to n) cof[i][j]*X[N[j]]<=b[i] X[j]>=0
對於第i個式子新增變量X[B[i]]變爲
X[B[i]]+∑(j=1 to n) cof[i][j]*X[N[j]]=b[i]
X[]>=0
然後從N[j]中選出目標函數係數>0且編號最小的
設爲pos
則一定有X[pos]<=b[i]/cof[i][pos] 找出最緊的鬆弛條件 設爲第id個
則把X[pos]用含X[B[id]]的式子表示出來 帶入每個式子 同時將id,pos互換
邊界條件就是目標函數的所有係數<0 則答案就是剩下的常數
具體可以參考http://wenku.baidu.com/view/ce5784754a7302768f99391d的例子
對於本題 用對偶的辦法 轉化問題
對於樣例我們有式子
Min 2x[1]+5x[2]+2x[3]
x[1] >=2
x[1]+x[2] >=3
x[2]+x[3]>=4
那麼對偶過來就變成
Max 2x[1]+3x[2]+4x[3]
x[1]+x[2] <=2
x[2]+x[3]<=5
x[3]<=2
計算即可
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
const int maxn=1010;
-
const int maxm=10010;
-
const double inf=0x3f3f3f3f3f3f3f3f;
-
const double eps=1e-9;
-
-
int n,m;
-
-
double cof[maxm][maxn],b[maxm],c[maxn],ans;
-
-
inline void pivot(int id,int pos)
-
{
-
cof[id][pos]=1/cof[id][pos];
-
b[id]*=cof[id][pos];
-
for(int i=1;i<=n;i++) if(i!=pos) cof[id][i]*=cof[id][pos];
-
for(int i=1;i<=m;i++)
-
if(i!=id&&fabs(cof[i][pos])>eps)
-
{
-
b[i]-=cof[i][pos]*b[id];
-
for(int j=1;j<=n;j++)
-
if(j!=pos)
-
cof[i][j]-=cof[i][pos]*cof[id][j];
-
cof[i][pos]=-cof[i][pos]*cof[id][pos];
-
}
-
ans+=c[pos]*b[id];
-
for(int i=1;i<=n;i++)
-
if(i!=pos)
-
c[i]-=c[pos]*cof[id][i];
-
c[pos]=-c[pos]*cof[id][pos];
-
}
-
-
inline double simplex()
-
{
-
while(true)
-
{
-
int pos,id;
-
for(pos=1;pos<=n;pos++) if(c[pos]>eps) break;
-
if(pos==n+1) return ans;
-
double tmp=inf;
-
for(int i=1;i<=m;i++)
-
if(cof[i][pos]>eps&&b[i]/cof[i][pos]<tmp)
-
tmp=b[i]/cof[i][pos],id=i;
-
if(tmp==inf) return inf;
-
pivot(id,pos);
-
}
-
}
-
-
int main()
-
{
-
scanf("%d%d",&n,&m);
-
for(int i=1;i<=n;i++)
-
scanf("%lf",&c[i]);
-
for(int i=1;i<=m;i++)
-
{
-
int l,r;
-
scanf("%d%d",&l,&r);
-
for(int j=l;j<=r;j++)
-
cof[i][j]=1;
-
scanf("%lf",&b[i]);
-
}
-
printf("%lld\n",(long long)(simplex()+0.5));
-
}
-
http://blog.csdn.net/wxh010910/article/details/53351853