zoukankan      html  css  js  c++  java
  • 【JSOI2016】最佳团体 [分数规划 树形DP]

    P4322 [JSOI2016]最佳团体
    二分+树形dp

    树形dp部分就和选课一样 就是r按照最保险的来赋的话会超时...

    然后看了大佬的代码大佬r=3.3 QAQ

    会T的那种
    #define ll long long
    #define Abs(x) ((x)<0?-(x):(x))
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)<(y)?(x):(y))
    const int N=2500+5,M=1000+5,INF=1e9+7,inf=0x3f3f3f3f;
    const double eps=1e-5;
    int n,K,tj[N],a[N],b[N];
    template void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    int head[N],tot=0;
    struct edge{int v,nxt;}e[N<<1];
    void add(int u,int v){
    	e[++tot]=(edge){v,head[u]},head[u]=tot;
    }
    double d[N],f[N][N];
    int sz[N];
    void dfs(int u,int fa){
    	sz[u]=1;
    	for(int i=head[u],v;i;i=e[i].nxt){
    		v=e[i].v;
    		if(v==fa) continue;
    		dfs(v,u);
    		sz[u]+=sz[v];
    		for(int j=Min(K+1,sz[u]);j;--j)
    		for(int k=0;k0;
    }
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(K),rd(n);
    	double l=0.0,r=3.3,mid;
    	for(int i=2;i<=n+1;++i) rd(b[i]),rd(a[i]),rd(tj[i]),add(++tj[i],i);//,,add(i,tj[i]);r=Max(r,(double)a[i]/b[i])
    	while(r-l>=eps){
    		mid=(l+r)/2;
    		if(check(mid)) l=mid;
    		else r=mid;
    	}
    	printf("%.3f",l);
    	return 0;
    }
    
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define Abs(x) ((x)<0?-(x):(x))
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)<(y)?(x):(y))
    const int N=2500+5,M=1000+5,INF=1e9+7,inf=0x3f3f3f3f;
    const double eps=1e-5;
    int n,K,tj[N],a[N],b[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int v,nxt;}e[N<<1];
    void add(int u,int v){
    	e[++tot]=(edge){v,head[u]},head[u]=tot;
    }
    
    double d[N],f[N][N];
    int sz[N];
    void dfs(int u,int fa){
    	sz[u]=1;
    	for(int i=head[u],v;i;i=e[i].nxt){
    		v=e[i].v;
    		if(v==fa) continue;
    		dfs(v,u);
    		sz[u]+=sz[v];
    		for(int j=Min(K+1,sz[u]);j;--j)
    		for(int k=0;k<Min(sz[v]+1,j);++k)
    		f[u][j]=Max(f[u][j],f[u][j-k]+f[v][k]);
    	}
    }
    
    bool check(double mid){
    	memset(f,0xc2,sizeof(f));
    	for(int i=1;i<=n+1;++i) f[i][1]=d[i]=(double)a[i]-mid*b[i],f[i][0]=0.0;
    	dfs(1,0);
    	return f[1][K+1]>0;
    }
    
    int main(){
    	freopen("in.txt","r",stdin);
    	rd(K),rd(n);
    	double l=0.0,r=3.3,mid;
    	for(int i=2;i<=n+1;++i) rd(b[i]),rd(a[i]),rd(tj[i]),add(++tj[i],i);//,,add(i,tj[i]);r=Max(r,(double)a[i]/b[i])
    	while(r-l>=eps){
    		mid=(l+r)/2;
    		if(check(mid)) l=mid;
    		else r=mid;
    	}
    	printf("%.3f",l);
    	return 0;
    }
    

    另一种先处理出时间戳的树形dp 先咕一下QAQ

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11361814.html
Copyright © 2011-2022 走看看