• [51nod1474]宝藏图


      有n堆宝藏,每一堆宝藏有一个挖掘所需要的时间ti,有一个价值qi。

      现在是做一个宝藏图。这个宝藏图是这样的,宝藏图的形状是一棵二叉树,二叉树刚好有k个叶子结点,从n堆宝藏中选k堆放到二叉树的叶子结点上,每个叶子结点只能放一堆宝藏,每堆宝藏只能放到一个叶子结点上。然后派k个人去找宝藏,每个人会分配到一个宝藏供他查找,在这k个宝藏中,每一个宝藏都会被分配给某一个人,k个人从根结点出发,每个人从当前结点往相邻结点走的时候要花费一个单位的时间,到达他指定的宝藏的时候,他要花费那个宝藏所需要的挖掘时间去挖掘那个宝藏,然后他获得那个宝藏的时间就是他行走的时间+挖掘时间。但是大家必须在T的时间内得到宝藏,所以现在要求在大家能在T时间内得到宝藏的情况下,使得宝藏的总价值最大。

      注意:可以不经过任何中间结点直接到达宝藏进行挖掘(样例二)。

     Input
      单组测试数据。
      第一行包含两个整数n 和T (1 ≤ n,T ≤ 100000),表示宝藏的数目和时间限制。
      接下来n行,每行有两个整数ti, qi (1 ≤ ti ≤ T, 1 ≤ qi ≤ 1000),第i个宝藏的挖掘时间和它的价值。
     Output
      输出最大的宝藏总价值。

      连暴力都不会写系列。

      cf官网给出了O(n^2T)的做法。。。从底往上一层一层算,f[h][w]表示第h层,这层已确定要有w个节点。

      每次枚举这一层有x个叶子节点,就能从f[h][w]转移到f[h-1][(w+x+1)/2]...

      之后看了cf上别人的AC代码。。在同一层里直接贪心把相邻最大的连向同个父亲就好了.....

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #include<cstdlib>
     8 #define ll long long
     9 #define ull unsigned long long
    10 #define ui unsigned int
    11 #define d double
    12 #define ld long double
    13 using namespace std;
    14 const int maxn=100233,modd=1000000007;
    15 struct zs{int t,v;}a[maxn];
    16 int mp[2][maxn],num[2];
    17 int i,j,k,n,m;
    18 
    19 
    20 int ra,fh;char rx;
    21 inline int read(){
    22     rx=getchar(),ra=0,fh=1;
    23     while(rx<'0'&&rx!='-')rx=getchar();
    24     if(rx=='-')fh=-1,rx=getchar();
    25     while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra*fh;
    26 }
    27 
    28 bool operator <(zs a,zs b){return a.t<b.t;}
    29 bool cmp(int a,int b){return a>b;}
    30 int main(){
    31     int n=read(),T=read();register int i,j;
    32     for(i=1;i<=n;i++)a[i].t=read(),a[i].v=read();
    33     sort(a+1,a+1+n);int top=1;bool now=1,pre=0;
    34     
    35     
    36     for(i=1;i<=T;i++,now^=1,pre^=1){
    37         while(top<=n&&a[top].t==i)mp[pre][++num[pre]]=a[top++].v;
    38         sort(mp[pre]+1,mp[pre]+1+num[pre],cmp);
    39 //            for(j=1;j<=num[pre];j++)printf("%d  ",mp[pre][j]);puts("");
    40         if(i==T)return printf("%d
    ",mp[pre][1]),0;
    41         if(num[pre]&1)mp[pre][++num[pre]]=0;
    42         
    43         for(j=1,num[now]=0;j<num[pre];j+=2)mp[now][++num[now]]=mp[pre][j]+mp[pre][j+1];
    44     }
    45 }
    View Code
  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5952713.html
Copyright © 2020-2023  润新知