[JSOI2016]最佳团体

[JSOI2016]最佳团体

#include <bits/stdc++.h>
using namespace std;
inline int read(){
	char ch=getchar();
	int s=0,f=1;
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f*=-1;
	for(; isdigit(ch);ch=getchar()) s*=10,s+=ch-'0';
	return s*f;
}
const int N = 3010;
const int inf = 1e9;
int n,k,siz[N];
struct oier{
	int v,w;//花费和战斗力
}a[N];
vector<int> v[N];
double dp[N][N],num[N];
void dfs(int x,int fa){
	dp[x][1]=num[x];
	siz[x]=1;
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(to==fa) continue;
		dfs(to,x);
		siz[x]+=siz[to];
		for(int j=min(siz[to],k+1);j>=1;j--)
			for(int l=0;l<=min(siz[to],j-1);l++)
				dp[x][j]=max(dp[x][j],dp[x][j-l]+dp[to][k]);
	}
}
bool check(double x){
	num[0]=0;
	for(int i=1;i<=n;i++)
		num[i]=(double)a[i].w-a[i].v*x;
	for(int i=0;i<=n;i++)
		for(int j=1;j<=m+1;j++)
			dp[i][j]=-inf;
	dfs(0,-1);
	return dp[0][k+1]<0;
}
int main(){
	k=read(),n=read();
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].v,&a[i].w);
		int x=read();
		v[x].push_back(i);
	}
	double l=0,r=10000;
	while(r-l<=1e-6){
		double mid=(l+r)/2;
		if(check(mid)) r=mid;
		else l=mid;
	}
	printf("%.3lf\n",l);
	return 0;
}
posted @ 2022-11-10 20:36  羊扬羊  阅读(22)  评论(0编辑  收藏  举报