• 20191111luogu3961黄金矿工 | 斜率 | 分组背包dp


    luogu3961黄金矿工

    题意:

    从(0,0)点取黄金,黄金的坐标破(x,y),取这个黄金所需时间t,价值v,在与原点同一条连线上的黄金需要先取最近的才能取后面的,求T时间内能获得的最大价值

    dp:

    首先预处理,求出每个点与原点连线的斜率,按斜率和与原点距离从小到大排序,把斜率相同的点分为一组,预处理出这一组选i个物品所需时间与所得价值,再分组背包dp即可

    时间复杂度:

    O(nt)

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 #define db double
     5 struct node
     6 {
     7     int x,y,t,v;
     8     db k;
     9 }a[2005];
    10 bool cmp(node x,node y)
    11 {
    12     if(x.k == y.k)return x.y < y.y;
    13     return x.k < y.k;
    14 }
    15 int N,T,cnt;
    16 int num[2005],v[2005][2005],t[2005][2005];
    17 int f[40005];
    18 int main()
    19 {
    20     scanf("%d%d",&N,&T);
    21     for(int i= 1;i <= N;i ++)
    22     {
    23         scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].t,&a[i].v);
    24         a[i].k = (db)((db)a[i].y / (db)a[i].x);
    25     }
    26     sort(a + 1,a + 1 + N,cmp);
    27     for(int i = 1;i <= N;i ++)
    28     {
    29         if(a[i].k != a[i - 1].k)cnt ++;
    30         num[cnt]++;//如果不写在外面就会80????? 
    31         v[cnt][num[cnt]] = v[cnt][num[cnt] - 1] + a[i].v;
    32         t[cnt][num[cnt]] = t[cnt][num[cnt] - 1] + a[i].t;
    33     }
    34     for(int i = 1;i <= cnt;i ++)
    35         for(int j = T;j >= t[i][1];j --)
    36             for(int k = 1;k <= num[i];k ++)
    37                 if(j >= t[i][k])f[j] = max(f[j],f[j - t[i][k]] + v[i][k]);
    38     printf("%d
    ",f[T]);
    39     return 0;
    40 }
  • 相关阅读:
    W3C规范
    背景图片调整大小
    comfirm和prompt的区别
    position属性absolute与relative 的区别
    text-decoration和text-indent和text-shadow
    刷新网页跳转锚点
    安卓中location.href或者location.reload 不起作用
    $_SERVER 当前信息
    堆+思维——cf1330E
    树形dp——cf1332F【好题】
  • 原文地址:https://www.cnblogs.com/djfuuxjz/p/11836729.html
Copyright © 2020-2023  润新知