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();
}