题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4753
0/1分数规划裸题。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define db double using namespace std; const int N=2505; const db eps=1e-5,INF=1e8; int n,k,s[N],p[N],hd[N],xnt,to[N],nxt[N],siz[N]; db ans,l,r,mid,a[N],dp[N][N]; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return fx?ret:-ret; } void add(int x,int y) { to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt; } void dfs(int cr) { dp[cr][1]=a[cr]; siz[cr]=1; for(int j=2;j<=k;j++) dp[cr][j]=-INF; for(int i=hd[cr],v;i;i=nxt[i]) { dfs(v=to[i]); for(int j=min(k,siz[cr]+siz[v]);j>=1;j--) for(int l=max(1,j-siz[cr]);l<=siz[v]&&l<j;l++) dp[cr][j]=max(dp[cr][j],dp[v][l]+dp[cr][j-l]); siz[cr]+=siz[v]; } } bool check() { for(int i=1;i<=n;i++) a[i]=p[i]-s[i]*mid; dfs(0); return dp[0][k]>=0; } int main() { k=rdn()+1; n=rdn(); for(int i=1,d;i<=n;i++) { s[i]=rdn(); p[i]=rdn(); d=rdn(); add(d,i); r+=p[i]; } for(int i=0;i<=n;i++) dp[i][0]=-INF; while(r-l>eps) { mid=(l+r)/2; if(check()) ans=mid,l=mid+eps; else r=mid-eps; } printf("%.3lf ",ans); return 0; }