UVa1410/LA4027 Expensive Drink

UVa1410/LA4027 Expensive Drink

题目链接

  本题是2007年icpc亚洲区域赛北京赛区的E题

题意

  你家那个调皮的小妹妹把水、牛奶、红酒混在一起,还加了点糖,打算给你喝。为了不让自己看上去太不讲理,她说如果你能猜到调制这种"混合饮料"花了多少钱,就可以逃此一劫(别告诉我你想喝它!)。调制饮料的费用等于所有原料的费用。具体来说,如果一种饮料分别用了 a1, a2, a3, a4 个单位的水、牛奶、红酒和糖,并且它们的单位价格分别为 c1,c2,c3,c4,则调制饮料的花费为 a1c1+a2c2+a3c3+a4c4。

  你并不清楚这 4 样东西的市场价格是多少,但是根据常识,0≤c1≤c2≤c3。为了帮助你解决这个难题,小妹妹向你提供了这种饮料中液体的用量(即 a1,a2,a3)和另外 n(n≤100)种混合饮料的液体用量(即 a1,a2,a3)和花费。尽管所有饮料中糖的用量都是未知的,但她向你保证,在上述任何一种混合饮料中,糖的花费 a4c4 一定在区间L,R中。

  凭借平日的了解,你断定她一定采用最贵的原料,因此你的任务是计算眼下这杯饮料的调制费用的最大值。如果她提供的信息有误,输出"Inconsistent data";如果费用可以任意大,输出"Too expensive!"。

分析

  线性规划模板题,要注意选择高效的单纯形算法模板(否则可能TLE)。另外有一个坑点:本地卡阈值,eps 推荐用 1e-8。

AC 代码

cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

#define INF 1e200
#define eps 1e-8
#define M 205
#define N 4
double a[M][N]; int B[M], C[N], m, n, L, R, kase = 0;

void pivot(int r, int c) {
    double t = a[r][c]; int e = C[c]; C[c] = B[r]; B[r] = e; a[r][c] = 1.;
    for (int i = 0; i <= n; ++i) a[r][i] /= t;
    for (int i = 0; i <= m; ++i) if (i != r && abs(a[i][c]) > eps){
        t = a[i][c]; a[i][c] = 0;
        for (int j = 0; j <= n; j++) a[i][j] -= a[r][j] * t;
    }
}

bool feasible() {
    while (true) {
        int r = -1, c = -1;
        for (int i = 0; i < m; i++) if (a[i][n] < -eps && (r < 0 || (rand() & 1))) r = i;
        if (r < 0) break;
        for (int i = 0; i < n; i++) if (a[r][i] < -eps && (c < 0 || (rand() & 1))) c = i;
        if (c < 0) return false;
        pivot(r, c);
    }
    return true;
}

int simplex() {
    for (int i = 0; i < n; i++) C[i] = i;
    for (int i = 0; i < m; i++) B[i] = n+i;
    if (!feasible()) return 0;
    while (true) {
        int r = -1, c = -1; double p = INF;
        for (int i = 0; i < n; i++) if (a[m][i] > eps) {
            c = i; break;
        }
        if (c < 0) break;
        for (int i = 0; i < m; i++) if (a[i][c] > eps) {
            double v = a[i][n] / a[i][c];
            if (v < p) r = i, p = v;
        }
        if (r < 0) return -1;
        pivot(r, c);
    }
    return 1;
}

void solve() {
    cin >> L >> R; m = n+1 << 1;
    for (int i=0; i<n; ++i) {
        for (int j=0; j<3; ++j) cin >> a[i][j], a[i+n][j] = -a[i][j];
        int p; cin >> p;
        a[i][3] = p - L; a[i+n][3] = R - p;
    }
    a[m-2][0] = 1.; a[m-2][1] = -1.; a[m-2][2] = a[m-2][3] = 0.;
    a[m-1][0] = a[m-1][3] = 0.; a[m-1][1] = 1.; a[m-1][2] = -1.;
    a[m][n = 3] = -R;
    for (int i=0; i<3; ++i) cin >> a[m][i];
    int r = simplex();
    cout << "Case " << ++ kase << ": ";
    if (r == 0) cout << "Inconsistent data" << endl;
    else if (r < 0) cout << "Too expensive!" << endl;
    else cout << -a[m][n] + eps << endl;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(4);
    while (cin >> n && n) solve();
    return 0;
}
相关推荐
漂流瓶jz10 天前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
零衣贰20 天前
The 2026 ICPC Asia East Continent Online Contest (I) 题解
c++·icpc
漂流瓶jz1 个月前
UVA-1609 不公平竞赛 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·链表·贪心·aoapc·算法竞赛入门经典·uva
漂流瓶jz2 个月前
UVA-12174 Shuffle的播放记录 题解答案代码 算法竞赛入门经典第二版
数据结构·c++·算法·图论·滑动窗口·算法竞赛入门经典·uva
漂流瓶jz2 个月前
UVA-12627 奇怪的气球膨胀 题解答案代码 算法竞赛入门经典第二版
算法·图论·递归·aoapc·算法竞赛入门经典·uva·12627
闻缺陷则喜何志丹2 个月前
【计算几何 第四章】线性规划:铸模制造
数学·计算几何·线性规划·铸造
星马梦缘3 个月前
算法设计 期末复习笔记
算法·动态规划·二分图·最小生成树·线性规划·最大流
星马梦缘3 个月前
算法设计-图论相关课堂笔记
二分图·最小生成树·线性规划·单源最短路·迪杰斯特拉·多源最短路·bellford算法
星马梦缘4 个月前
算法设计与分析 作业三 答案与解析
算法·线性规划·二分图匹配·多元最短路·流网络·bellmanford·匈牙利树算法