bzoj4753

bzoj4753 树形dp+01分数规划

这是一个典型的树形背包+01分数规划。看见分数形式最大就应该想到01分数规划。

于是套用分数规划,每次用树形背包检验。

首先这是一棵树,不是一个森林,所以我们不用添加虚点。然后可以列出dp方程,具体代码。

然后每个点如果自己选了,那么父亲也要选,所以更新的时候,除了jyy也就是0号节点,都是从dp[u][1]开始更新,而且初值就是dp[u][0]=0,dp[u][1]=val,因为儿子选了,自己肯定会选,所以不能出现

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

每次背包要从大到小枚举,常见技巧。

然后判断即是dp[0][k]>=0。

但是又有一个问题:val[0]是什么?如果是0的话,那么不就无法判断了?

那么我们这么设置一下,当u=0时,j可以枚举到0,因为jyy不算在k里,所以jyy就可以出现dp[0][i]=dp[0][0]+dp[v][i]的情况。但是val[0]还是设置成-inf,这样才可以取到最大值,否则一上来dp[0][1]就是0了。

#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;
}

时间: 2024-11-05 21:59:43

bzoj4753的相关文章

【bzoj4753】[Jsoi2016]最佳团体 分数规划+树形背包dp

题目描述 JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一位编号比他小的候选人Ri推荐.如果Ri=0则说明这个候选人是JYY自己看上的.为了保证团队的和谐,JYY需要保证,如果招募了候选人i,那么候选人Ri"也一定需要在团队中.当然了,JYY自己总是在团队里的.每一个候选人都有一个战斗值Pi",也有一个招募费用Si".JYY希望招募K个候选人(JYY自己不算),组成一个性价比最高的团队.也就是,这K个被JYY选择的候

BZOJ4753: [Jsoi2016]最佳团体

Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 844  Solved: 318[Submit][Status][Discuss] Description JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一位 编号比他小的候选人Ri推荐.如果Ri=0则说明这个候选人是JYY自己看上的.为了保证团队的和谐,JYY需要保证, 如果招募了候选人i,那么候选人Ri"也一定需要在团队中.当然了,JYY

bzoj4753 最佳团体

题目描述 JSOI 信息学代表队一共有 NN 名候选人,这些候选人从 11 到 NN 编号.方便起见,JYY 的编号是 00 号.每个候选人都由一位编号比他小的候选人R_iRi? 推荐.如果 R_i = 0Ri?=0?,则说明这个候选人是 JYY 自己看上的. 为了保证团队的和谐,JYY 需要保证,如果招募了候选人 ii,那么候选人 R_iRi? 也一定需要在团队中.当然了,JYY 自己总是在团队里的.每一个候选人都有一个战斗值 P_iPi? ,也有一个招募费用 S_iSi? .JYY 希望招募