# LOJ3664 「JOI 2022 Final」选举

## 题目大意

$$N$$ 个州，每个州有两个参数：$$A_i$$, $$B_i$$，满足 $$A_i\leq B_i$$

## 参考代码

// problem: LOJ3664
#include <bits/stdc++.h>
using namespace std;

#define mk make_pair
#define fi first
#define se second
#define SZ(x) ((int)(x).size())

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template<typename T> inline void ckmax(T& x, T y) { x = (y > x ? y : x); }
template<typename T> inline void ckmin(T& x, T y) { x = (y < x ? y : x); }

const int MAXN = 500;
const int INF = 1e9;
int n, K, lim;
struct State {
int a, b;
} s[MAXN + 5], sa[MAXN + 5][MAXN + 5];
bool cmpB(State s1, State s2) {
return s1.b < s2.b;
}
bool cmpA(State s1, State s2) {
return s1.a < s2.a;
}
double dp[MAXN + 5][MAXN + 5];

int main() {
cin >> n >> K;
lim = n;
for (int i = 1; i <= n; ++i) {
cin >> s[i].a >> s[i].b;
if (s[i].b == -1) {
s[i].b = INF;
--lim; // max number of collaborators
}
}

sort(s + 1, s + n + 1, cmpB); // sort by B

for (int i = 1; i <= n; ++i) { // the last i states, sorted by A
for (int j = 1; j <= i; ++j) {
sa[i][j] = s[n - j + 1];
}
sort(sa[i] + 1, sa[i] + i + 1, cmpA);
}

double ans = INF;
for (int x = 0; x <= lim && x <= K; ++x) { // number of collaborators

for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
dp[i][j] = INF;
dp[0][0] = 0;
for (int i = 1; i <= lim && i <= K; ++i) {
for (int j = 0; j < i && j < x; ++j) { // how many collaborators made in the first (i - 1) states
// make a collaborator in state i
// dp[i - 1][j] -> dp[i][j + 1]
ckmin(dp[i][j + 1], dp[i - 1][j] + (double)s[i].b / (j + 1));

// don't make any collaborator in state i
// dp[i - 1][j] -> dp[i][j]
ckmin(dp[i][j], dp[i - 1][j] + (double)s[i].a / (x + 1));
}
}

for (int p = x; p <= lim && p <= K; ++p) { // the position of the last collaborator
// select (K - p) states from the last (n - p) states
double cost = 0;
for (int i = 1; i <= K - p; ++i) {
cost += (double)sa[n - p][i].a / (x + 1);
}
ckmin(ans, dp[p][x] + cost);
}
}
cout << setiosflags(ios :: fixed) << setprecision(10) << ans << endl;
return 0;
}

posted @ 2022-02-26 16:56  duyiblue  阅读(473)  评论(2编辑  收藏  举报