1. 程式人生 > >ZOJ3068(01分數規劃)

ZOJ3068(01分數規劃)

all pac 分數 res per () get 2.0 ble

本是POJ2976,喜聞樂見的01規劃入門題。POJ日常假死,到ZOJ測。
二分答案。
試了試數據好像沒問題,\(a_i\)總是小於\(b_i\)且最終預答案l都小於1。然而為什麽我把r設成1e10往上就會WA,設成1或者1e3會AC,設成1e2會WA……而且網上題解基本都會被全0的數據hack啊……求解答

#include <cstdio>
#include <cctype>
#include <algorithm>
#define mset(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define fg cout << "--------------\n";
#define debug(x) std::cerr << #x << " = " << x << std::endl
#define All(x) (x.begin()), (x.end())
using namespace std;

typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 1e18;

template <typename T> void read(T &x) {
    x = 0;
    int s = 1, c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')   s = -1;
    for (; isdigit(c); c = getchar())
        x = x * 10 + c - 48;
    x *= s;
}

template <typename T> void write(T x) {
    if (x < 0)  x = -x, putchar('-');
    if (x > 9)  write(x / 10);
    putchar(x % 10 + '0');
}

template <typename T> void writeln(T x) {
    write(x);
    puts("");
}

const int maxn = 1e3 + 5;
const db eps = 1e-4;
int n, k;
db a[maxn], b[maxn], c[maxn];

bool not_ok(db mid) {
    db res = 0;
    rep(i, 1, n)    c[i] = a[i] - b[i] * mid, res += c[i];
    sort(c + 1, c + 1 + n);
    rep(i, 1, k)    res -= c[i];
    return res < 0;
}

int main() {
    while (~scanf("%d %d", &n, &k) && (n | k)) {
        db x = 0;
        rep(i, 1, n)    read(a[i]), x += a[i];
        rep(i, 1, n)    read(b[i]);
        if (x == 0.0) {
            puts("0"); continue;
        }
        db l = 0, r = 1;
        while (r - l > eps) {
            db mid = (l + r) / 2.0;
            if (not_ok(mid))    r = mid;
            else    l = mid;    
        }
        printf("%.0lf\n", l * 100.0);
    }   
    return 0;
}

ZOJ3068(01分數規劃)