Gym - 101002D：Programming Team （01分数规划+树上依赖背包）

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2610;
const double inf=1e20;
double dp[maxn][maxn],s[maxn],p[maxn],val[maxn];
int r[maxn],Laxt[maxn],Next[maxn],To[maxn];
int pos[maxn],tot,cnt,N,K,sz[maxn];
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs(int u)
{
sz[u]=1; tot++; pos[tot]=u;
for(int i=Laxt[u];i;i=Next[i]){
dfs(To[i]); sz[u]+=sz[To[i]];
}
}
bool check(double Mid)
{
rep(i,1,N) val[i]=p[i]-s[i]*Mid;
rep(i,1,tot+1) rep(j,1,K) dp[i][j]=-inf;
rep(i,0,tot+1) dp[i][0]=0;
for(int i=tot;i>=1;i--){
int x=pos[i];
for(int j=1;j<=K;j++){
dp[i][j]=max(dp[i+1][j-1]+val[x],dp[i+sz[x]][j]);
}
}
return dp[1][K]>=0;
}
int main()
{
scanf("%d%d",&K,&N); K++;
rep(i,1,N){
scanf("%lf%lf%d",&s[i],&p[i],&r[i]);
}
dfs(0);
double L=0,R=10000,Mid,ans=0; int T=30;
while(T--){
Mid=(L+R)/2;
if(check(Mid)) ans=max(Mid,ans),L=Mid;
else R=Mid;
}
printf("%.3lf\n",ans);
return 0;
}

posted @ 2019-03-17 19:14  nimphy  阅读(...)  评论(...编辑  收藏