一、题目描述:
给你一颗
你需要选择
约束:选择一个节点之前,必须先选择它的父亲节点。(根节点除外)
输出
数据范围
二、解题思路:
是我以前从未见过的分数规划题目。
分数规划题的形式就是让你求
其实写了一道题就不难了,个人觉得比较套路。一般我们二分求解分数规划。过程如下:
于是就是比较板的树形背包题了,时间复杂度
三、完整代码:
1 #include<iostream> 2 #include<iomanip> 3 #include<algorithm> 4 #define N 3010 5 #define ll long long 6 #define rep(i,l,r) for(int i=l;i<=r;i++) 7 #define per(i,r,l) for(int i=r;i>=l;i--) 8 #define tep(i,u) for(int i=head[u];i!=-1;i=e[i].nxt) 9 using namespace std; 10 int n,m,s[N]; 11 double g[N],v[N],w[N],f[N][N]; 12 struct EDGE{ 13 int v,nxt; 14 }e[N*2]; 15 int head[N],cnt; 16 void add(int u,int v){ 17 e[++cnt].v=v; 18 e[cnt].nxt=head[u]; 19 head[u]=cnt; 20 } 21 void Max(double &a,double b){a=max(a,b);} 22 void solve(int u,int ff){ 23 tep(i,u){ 24 if(e[i].v==ff) continue; 25 int to=e[i].v;solve(to,u); 26 per(j,min(s[u]+s[to],m),2) 27 rep(k,max(1,j-s[u]),min(s[to],j-1)) 28 Max(f[u][j],f[u][j-k]+f[to][k]); 29 s[u]+=s[to]; 30 } 31 } 32 bool check(double val){ 33 rep(i,1,n) 34 g[i]=v[i]-val*w[i]; 35 rep(i,0,n) 36 rep(j,0,m) 37 f[i][j]=-1e9; 38 rep(i,0,n) 39 s[i]=1,f[i][1]=g[i]; 40 solve(0,0); 41 return f[0][m]>=0; 42 } 43 int main(){ 44 ios::sync_with_stdio(false); 45 cin.tie(0);cout.tie(0); 46 cin>>m>>n;m++; 47 rep(i,0,n) 48 head[i]=-1; 49 rep(i,1,n){ 50 cin>>w[i]>>v[i]; 51 int ff;cin>>ff,add(ff,i); 52 } 53 double l=0,r=1e4,eps=0.0003; 54 while(l+eps<=r){ 55 double mid=(l+r)/2; 56 if(check(mid)) l=mid+eps; 57 else r=mid-eps; 58 } 59 cout<<fixed<<setprecision(3)<<l<<'\n'; 60 return 0; 61 }
四、写题心得:
收获经验如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探