[BZOJ]4753: [Jsoi2016]最佳团体 01分数规划+树形DP
来源:互联网 发布:阿里云 腾讯云 香港 编辑:程序博客网 时间:2024/05/23 21:29
Description
JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号。方便起见,JYY的编号是0号。每个候选人都由一位编号比他小的候选人Ri推荐。如果Ri=0则说明这个候选人是JYY自己看上的。为了保证团队的和谐,JYY需要保证,如果招募了候选人i,那么候选人Ri”也一定需要在团队中。当然了,JYY自己总是在团队里的。每一个候选人都有一个战斗值Pi”,也有一个招募费用Si”。JYY希望招募K个候选人(JYY自己不算),组成一个性价比最高的团队。
也就是,这K个被JYY选择的候选人的总战斗值与总招募总费用的比值最大。
题解:
今天学了下01分数规划,大概是解决这样一个问题:有一些东西,只能选或者不选,每个东西有a[i],b[i]两个值,使得最后Sigma(a[i])/Sigma(b[i])最大(或最小)。既然要最大,那么Sigma(a[i])/Sigma(b[i])>=x,就要求这个x最大,我们可以二分这个x的值,然后转为判定性问题:是否存在Sigma(a[i]-x×b[i])>=0,对于这道题,我们可以做树形背包DP,每个点的价值就重新赋值为p[i]-mid×s[i],f[i][j]表示i这个点一定选,总共选了j个点的最大价值,最后看一下f[0][k]是否大于等于0就好了。树形DP的时候要注意,一定要尽量减少无效状态,具体地来说,就是从一个有效状态转移到另一个有效状态,否则会TLE。网上有对时间复杂度的证明,是
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int Maxn=2510;int size[Maxn],k,n,R[Maxn];double s[Maxn],p[Maxn],f[Maxn][Maxn],v[Maxn];struct Edge{int y,next;}e[Maxn];int last[Maxn],len=0;void ins(int x,int y){ int t=++len; e[t].y=y;e[t].next=last[x];last[x]=t;}void get(int x){ size[x]=1; for(int i=last[x];i;i=e[i].next) get(e[i].y),size[x]+=size[e[i].y];}void Clear(int x){ for(int i=0;i<=n;i++) f[x][i]=-2147483647.0;}void dfs(int x){ Clear(x); int tot=0; if(x)tot++,f[x][1]=v[x]; else f[x][0]=0.0; for(int i=last[x];i;i=e[i].next) { int y=e[i].y,d=(x)?1:0; dfs(y); for(int j=tot;j>=d;j--) for(int l=1;l<=size[y];l++) f[x][j+l]=max(f[x][j+l],f[x][j]+f[y][l]); tot+=size[y]; }}int main(){ double l=0.0,r=0.0; scanf("%d%d",&k,&n); for(int i=1;i<=n;i++) { scanf("%lf%lf%d",&s[i],&p[i],&R[i]); ins(R[i],i);r=max(r,p[i]); } get(0); int c=30; while(c--) { double mid=(l+r)/2.0; for(int i=1;i<=n;i++)v[i]=p[i]-mid*s[i]; dfs(0); if(f[0][k]>=0.0)l=mid; else r=mid; } printf("%.3lf",(l+r)/2.0);}
阅读全文
1 0
- [BZOJ]4753: [Jsoi2016]最佳团体 01分数规划+树形DP
- BZOJ 4753: [Jsoi2016]最佳团体 树形背包 01分数规划
- bzoj 4753: [Jsoi2016]最佳团体 二分答案+树形dp
- 【分数规划+DFS序上DP】BZOJ4753 [Jsoi2016]最佳团体
- BZOJ 4753: [Jsoi2016]最佳团体
- 4753: [Jsoi2016]最佳团体
- [二分+DFS序上DP]BZOJ 4753—— [Jsoi2016]最佳团体
- BZOJ4753 [Jsoi2016]最佳团体
- bzoj4753: [Jsoi2016]最佳团体
- bzoj4753: [Jsoi2016]最佳团体
- [bzoj4753][Jsoi2016]最佳团体 树上背包+二分
- bzoj 1486(01分数规划)
- bzoj 3232 01分数规划
- 【动态规划】【树形DP】[BZOJ 1040]骑士
- bzoj4753 最佳团体 树形背包
- bzoj 3232: 圈地游戏 01分数规划
- [BZOJ]5090: 组题 01分数规划
- Codeforce 489E(dp+01分数规划)
- 关于字符串拼接的问题
- 10.go开源cache2go项目笔记——mycachedapp调用
- node跨域问题
- POJ 2470 Relatives (欧拉函数)
- jAVA SpringBoot(1)---pom.xml文件基本配置
- [BZOJ]4753: [Jsoi2016]最佳团体 01分数规划+树形DP
- 三.java多线程之线程调度
- redis数据丢失及解决
- 4.go开源groupcache项目笔记——关于strconv
- RESTful API设计指南
- leetcode Minimum Absolute Difference in BST 二叉搜索树中的最小差
- Milking Time POJ
- 1022. D进制的A+B (20)
- 关于二叉树的结点