jsoi 資訊學代表隊一共有 nn 名候選人,這些候選人從 11 到 nn 編號。方便起見,jyy 的編號是 00 號。每個候選人都由一位編號比他小的候選人r_iri推薦。如果 r_i = 0ri=0,則說明這個候選人是 jyy 自己看上的。
為了保證團隊的和諧,jyy 需要保證,如果招募了候選人 ii,那麼候選人 r_iri也一定需要在團隊中。當然了,jyy 自己總是在團隊裡的。每乙個候選人都有乙個戰鬥值 p_ipi,也有乙個招募費用 s_isi。jyy 希望招募 kk 個候選人(jyy 自己不算),組成乙個價效比最高的團隊。也就是,這 kk 個被 jyy 選擇的候選人的總戰鬥值與總招募費用的比值最大。
輸入格式:
輸入一行包含兩個正整數 kk 和 nn 。
接下來 nn 行,其中第 ii 行包含三個整數 s_isi, p_ipi, r_iri, 表示候選人 ii 的招募費用,戰鬥值和推薦人編號。
輸出格式:
輸出一行乙個實數,表示最佳比值。答案保留三位小數。
這題涉及到了比值最大,最好用分數規劃來解決。
我們需要求出pi和ri的比值最大,不妨設σpi/σri>=x ,經過轉移σpi>=σri*x =>σpi-σri*x>=0. 由此可見,我們可以二分出來乙個x使這個值》=0.
然後我們可以用樹形dp來計算出最優值。
我們先dfs一遍得到每個樹上節點的dfs序(時間戳),令f[i][j]為dfs序為i的點,取j個的最優值。
如果當前點取,說明自己的子樹也可以取,所以f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+val[i]);
如果當前點不取,說明要取到下一顆樹,我們記錄size[i]代表以i為根的子樹的大小。根據dfs序的性質,我們知道下一顆和自己平行的子樹的dfs序為i+size.
所以轉移方程是:f[i+size[i]][j]=max(f[i+size[i]][j],f[i][j]);
//luogu-judger-enable-o2
#include #include
#include
#include
#include
#include
#define in(a) a=read()
#define maxn 200020
#define rep(i,k,n) for(int i=k;i<=n;i++)
using
namespace
std;
inline
intread()
intk,n;
int inf=99999999
;double p[2510],s[2510
];int total=0,to[2520],nxt[2510],head[2510
];int cnt=0,dfn[2510],ind[2510],size[2510
];double f[2510][2510],val[2510
];inline
void adl(int a,int
b)inline
void dfs(int
u)
return;}
inline
double dp(double
x) rep(i,
1,n+1
) rep(j,
0,k+1
) f[i][j]=-inf;
rep(i,
0,n)
rep(j,
0,min(i,k+1
))
/*rep(i,0,n)
intmain()
dfs(0);
val[
0]=0.0
;
double left=0.0,right=maxn;
while(right-left>0.00001
) printf(
"%.3lf
",left);
return0;
}/*2 41 2 0
2 2 0
1 3 1
2 3 1
*/
bzoj4753 最佳團體
jsoi 資訊學代表隊一共有 nn 名候選人,這些候選人從 11 到 nn 編號。方便起見,jyy 的編號是 00 號。每個候選人都由一位編號比他小的候選人r iri 推薦。如果 r i 0ri 0 則說明這個候選人是 jyy 自己看上的。為了保證團隊的和諧,jyy 需要保證,如果招募了候選人 ii...
bzoj 4753 最佳團體
written with stackedit.jsoi 資訊學代表隊一共有n名候選人,這些候選人從 1 到 n 編號。方便起見,jyy 的編號是 0 號。每個候選人都由一位編號比他小的候選人 r i 推薦。如果 r i 0 則說明這個候選人是 jyy 自己看上的。為了保證團隊的和諧,jyy 需要保證...
BZOJ4753 最佳團體(分數規劃,動態規劃)
bzoj jsoi資訊學代表隊一共有n名候選人,這些候選人從1到n編號。方便起見,jyy的編號是0號。每個候選人都由一位 編號比他小的候選人ri推薦。如果ri 0則說明這個候選人是jyy自己看上的。為了保證團隊的和諧,jyy需要保證,如果招募了候選人i,那麼候選人ri 也一定需要在團隊中。當然了,j...