# [BZOJ4753][Jsoi2016]最佳团体

## Description

JSOI信息学代表队一共有N名候选人，这些候选人从1到N编号。方便起见，JYY的编号是0号。每个候选人都由一位

1 2
1000 1 0
1 1000 1

## Sample Output

0.001

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define reg register
int res = 0;char ch=getchar();bool fu=0;
while(!isdigit(ch))fu|=(ch=='-'),ch=getchar();
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return fu?-res:res;
}
#define N 2505
int K, n;
int P[N], S[N];

struct edge {
int nxt, to;
}ed[N];
inline void add(int x, int y) {
}

double f[N][N], val[N];
int siz[N], dfn[N], tot;

void dfs(int x)
{
siz[x] = 1;
for (reg int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
dfs(to);
siz[x] += siz[to];
}
dfn[x] = ++tot;
}

void dp(int x)
{
siz[x] = 1;
for (reg int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
dp(to);
for (reg int j = siz[x] ; j >= 1 ; j --)
for (reg int p = 0 ; p <= siz[to] ; p ++)
f[x][j + p] = max(f[x][j + p], f[to][p] + f[x][j]);
siz[x] += siz[to];
}
}

int main()
{
dfs(0);
double l = 0, r = 1e4, mid(0);
while(r - l >= 1e-5)
{
mid = (l + r) / 2;
for (reg int i = 1 ; i <= n ; i ++) val[i] = 1.0 * P[i] - 1.0 * S[i] * mid;
for (reg int i = 0 ; i <= n ; i ++)
for (reg int j = 0 ; j <= K ; j ++)
f[i][j] = -1e9;
for (reg int i = 0 ; i <= n ; i ++) f[i][0] = 0;
for (reg int i = 0 ; i <= n ; i ++) f[i][1] = val[i];
dp(0);
if (f[0][K] >= 1e-5) l = mid;
else r = mid;
}
printf("%.3lf\n", l);
return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define reg register
int res = 0;char ch=getchar();bool fu=0;
while(!isdigit(ch))fu|=(ch=='-'),ch=getchar();
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return fu?-res:res;
}
#define N 2505
int K, n;
int P[N], S[N];

struct edge {
int nxt, to;
}ed[N];
inline void add(int x, int y) {
}

double f[N][N], val[N];
int siz[N], dfn[N], tot;

void dfs(int x)
{
siz[x] = 1;
for (reg int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
dfs(to);
siz[x] += siz[to];
}
dfn[x] = ++tot;
}

void dp(int x)
{
siz[x] = 1;
for (reg int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
dp(to);
siz[x] += siz[to];
}
for (reg int j = 1 ; j <= K ; j ++)
f[dfn[x]][j] = max(f[dfn[x] - siz[x]][j], f[dfn[x] - 1][j - 1] + val[x]);
}

int main()
{
dfs(0);
double l = 0, r = 1e7, mid(0);
while(r - l >= 1e-6)
{
mid = (l + r) / 2;
for (reg int i = 0 ; i <= n ; i ++)
{
f[i][0] = 0;
for (reg int j = 1 ; j <= K ; j ++)
f[i][j] = -1e9;
}
for (reg int i = 1 ; i <= n ; i ++) val[i] = 1.0 * P[i] - 1.0 * S[i] * mid;
dp(0);
if (f[tot][K] >= 1e-6) l = mid;
else r = mid;
}
printf("%.3lf\n", l);
return 0;
}

posted @ 2018-10-22 20:59  zZhBr  阅读(106)  评论(0编辑  收藏  举报