题目链接:https://www.luogu.org/problem/P4322
两个板子合一块
#include <bits/stdc++.h>
#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 pb push_back
using namespace std;
const int N = 2600;
int n,m;
int siz[N],a[N],b[N];
double s[N],dp[N][N];
vector<int>nxt[N];
void dfs(int u) { //时间复杂度O(N*M)
siz[u] = 1;
dp[u][0] = 0;
dp[u][1] = s[u];
for(auto v:nxt[u]) {
dfs(v);
per(i, min(siz[u],m), 1) {
int P = min(siz[v],m-i);
per(j, P, 0)
dp[u][i+j] = max(dp[u][i+j],dp[u][i]+dp[v][j]);
}
siz[u] += siz[v];
}
}
bool ok(double mid) {
rep(i, 0, n)
rep(j, 0, m)
dp[i][j] = -1e9;
rep(i, 1, n) s[i] = a[i]-mid*b[i];
dfs(0);
return dp[0][m]>=0;
}
int main() {
//freopen("a.txt","r",stdin);
scanf("%d%d",&m,&n);
rep(i, 1, n) {
int f;
scanf("%d%d%d",&b[i],&a[i],&f);
nxt[f].pb(i);
}
m++;
dfs(0);
double l = 0, r = 1e9;
rep(i, 1, 50) {
double mid = (l+r)/2;
if(ok(mid)) l = mid;
else r = mid;
}
printf("%.3f",l);
return 0;
}