日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷P4322 最佳团伙(树上dp)

發布時間:2023/12/3 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷P4322 最佳团伙(树上dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

洛谷傳送門
題目描述

JSOI 信息學代表隊一共有 N 名候選人,這些候選人從 1 到 N 編號。方便起見,JYY 的編號是 0 號。每個候選人都由一位編號比他小的候選人Ri推薦。如果 Ri=0,則說明這個候選人是 JYY 自己看上的。

為了保證團隊的和諧,JYY 需要保證,如果招募了候選人 iii,那么候選人 Ri? 也一定需要在團隊中。當然了,JYY 自己總是在團隊里的。每一個候選人都有一個戰斗值 Pi,也有一個招募費用 Si 。JYY 希望招募 K 個候選人(JYY 自己不算),組成一個性價比最高的團隊。也就是,這 K 個被 JYY 選擇的候選人的總戰斗值與總招募費用的比值最大。

解析

二分這個比值
再加上一些推導就可以轉化為樹上的nm背包問題
(nm背包傳送門)
這樣就完事了

#include <bits/stdc++.h> using namespace std; const int N=3000; int n,m; struct node{int to,nxt; }p[N]; int fi[N],cnt=-1,ru[N]; int pp[N],s[N],belong[N]; double P[N]; void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt; } int a,b,c; int pos[N],dfs[N],size[N],tot; void build(int x,int fa){size[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;build(to,x);size[x]+=size[to];}dfs[x]=++tot;pos[tot]=x; } double dp[N][N]; bool check(double mid){ // printf("\ncheck:%lf\n",mid);for(int i=1;i<=n;i++) P[i]=pp[i]-mid*s[i];for(int i=0;i<=tot;i++){for(int j=1;j<=m+1;j++) dp[i][j]=-2e9;}dp[0][0]=0;for(int i=1;i<=tot;i++){int id=pos[i];for(int j=m+1;j>=1;j--){dp[i][j]=max(dp[i-1][j-1]+P[id],dp[i-size[id]][j]); // printf("i=%d j=%d dp=%lf size=%d\n",i,j,dp[i][j],size[id]);}} // printf("%lf\n",dp[tot][m+1]);return dp[tot][m+1]>=0;} int main(){memset(fi,-1,sizeof(fi));scanf("%d%d",&m,&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&s[i],&pp[i],&belong[i]);addline(belong[i],i);}build(0,-1);double st=0,ed=1e5+100;while(ed-st>=0.00001){double mid=(st+ed)/2; // printf("st=%d ed=%d\n",st,ed);if(check(mid)) st=mid;else ed=mid;}printf("%.3lf",st);return 0; } /* 1 2 100 1000 0 1 1000 1 */

thanks for reading!

總結

以上是生活随笔為你收集整理的洛谷P4322 最佳团伙(树上dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。