bzoj4753

bzoj4753 树形dp+01分数规划

dp[u][i]=dp[u][0]+dp[v][i]这种情况。

#include<bits/stdc++.h>
using namespace std;
const int N = 2510;
const double inf = 1e9, eps = 1e-5;
int n, k;
int r[N], size[N];
double ans;
double dp[N][N], s[N], p[N], val[N];
vector<int> G[N];
void dfs(int u)
{
dp[u][0] = 0;
dp[u][1] = val[u];
++size[u];
for(int i = 0; i < G[u].size(); ++i)
{
int v = G[u][i];
dfs(v);
for(int j = min(size[u], k); j >= (u == 0 ? 0 : 1); --j)
for(int l = min(size[v], k); l >= 0; --l) if(j + l <= k)
{
//                printf("dp[%d][%d]=%.10f dp[%d][%d]=%.10f dp[%d][%d]=%.10f\n", u, l + j, dp[u][l + j], u, j, dp[u][j], v, l, dp[v][l]);
dp[u][l + j] = max(dp[u][l + j], dp[u][j] + dp[v][l]);
}
size[u] += size[v];
}

}
bool C(double x)
{
for(int i = 0; i <= n; ++i)
{
size[i] = 0;
val[i] = p[i] - s[i] * x;
for(int j = 0; j <= k; ++j) dp[i][j] = -inf;
}
dfs(0);
return dp[0][k] >= 0;
}
int main()
{
scanf("%d%d", &k, &n);
s[0] = inf;
for(int i = 1; i <= n; ++i)
{
scanf("%lf%lf%d", &s[i], &p[i], &r[i]);
G[r[i]].push_back(i);
}
double l = 0, r = 1e4 + 1, mid;
while(r - l > eps)
{
mid = (l + r) / 2.0;
if(C(mid)) l = ans = mid;
else r = mid;
}
printf("%.3f\n", ans);
return 0;
}
View Code

posted @ 2017-06-08 19:07  19992147  阅读(136)  评论(0编辑  收藏  举报