zoukankan      html  css  js  c++  java
  • zzuli 2172 队列优化dp

    2172: GJJ的日常之购物

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 9  Solved: 8

    SubmitStatusWeb Board

    Description

    一天,GJJ去购物,来到商场门口,GJJ计划要买n个商品,第i个商品的坐标为(xi,yi),重量是wi。
    GJJ比较任性,想按照商品编号从小到大的顺序将所有的商品的搬到车里(车在(0,0)的位置);
    GJJ可以几个商品一起搬,但在任何时候GJJ手中的商品重量不能超过最大载重C。
    商场的过道只有横着的和竖着的。求GJJ行走的最短距离(GJJ的起始位置为(0,0))。

    Input

    第一行输入一个T(T<=10),表示T组数据。
    每组数据第一行为最大载重C(1<=C<=100),商品个数n(n<=100000);
    接下来n行,每行为xi,yi,wi,(0<=xi,yi<=100,wi<=C)既商品的坐标和重量

    Output

    对于每组数据,输出总路径的最短长度。

    Sample Input

    2 10 4 1 2 3 1 0 3 3 1 4 3 1 4 5 1 1 1 2

    Sample Output

    14 4
    推了1h方程可惜是错误的= =。
    可以理解为取第i件物品时是取了前j件物品(j<i)放回车后,再次取i之前j之后的物品一次性取到i然后返回(如果可以的话).
    设f(i)表示为 将前i件物品放到车上的最短距离  d1[i]表示0->1->2......->i点所有距离之和     d2[i]表示0->i的距离
    那么我们有 f[i]=MIN{ f[j]+d2[j+1]+d1[i]-d1[j+1]+d2[i] | j<i&&j+1至i所有物品重量<=C }
                       f[i]=MIN{ f[j]+d2[j+1]-d1[j+1] }+d1[i]+d2[i] ;
    对于MIN里的显然我们可以维护一个最小值,优先队列即可完成,每计算出一个f[i]时就push进去一个 f[i]+d2[i+1]-d1[j-1],
    每次取队首时要判断是否满足重量条件,如果不满足直接pop,因为后面的更不会满足,这个节点已经没用。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define inf 0x3f3f3f3f
     5 int d1[100005],d2[100005],f[100005];
     6 int x[100005],y[100005],w[100005];
     7 struct node
     8 {
     9     int u,w;
    10     bool operator<(const node &tmp)const{
    11     return w>tmp.w;
    12     }
    13 };
    14 priority_queue<node>Q;
    15 int main()
    16 {
    17    // freopen("in.txt","r",stdin);
    18    int T,C,N,i,j,k;
    19    cin>>T;
    20    while(T--){
    21     while(!Q.empty()) Q.pop();
    22     cin>>C>>N;
    23     for(i=1;i<=N;++i)
    24     {
    25         scanf("%d%d%d",&x[i],&y[i],&w[i]);
    26         w[i]+=w[i-1];
    27         d1[i]=d1[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
    28         d2[i]=x[i]+y[i];
    29     }
    30     f[1]=d2[1]*2;
    31     Q.push(node{0,0});
    32     Q.push(node{1,f[1]+d2[2]-d1[2]});
    33     for(i=2;i<=N;++i)
    34     {
    35      node tmp=Q.top();
    36    while(!Q.empty()&&w[i]-w[tmp.u]>C){
    37         Q.pop();
    38         tmp=Q.top();
    39      }
    40      f[i]=tmp.w+d2[i]+d1[i];
    41      Q.push(node{i,f[i]-d1[i+1]+d2[i+1]});
    42     }
    43     cout<<f[N]<<endl;
    44    }
    45     return 0;
    46 }
    47 //注释freopen语句!!!
  • 相关阅读:
    Hdu 5396 Expression (区间Dp)
    Lightoj 1174
    codeforces 570 D. Tree Requests (dfs)
    codeforces 570 E. Pig and Palindromes (DP)
    Hdu 5385 The path
    Hdu 5384 Danganronpa (AC自动机模板)
    Hdu 5372 Segment Game (树状数组)
    Hdu 5379 Mahjong tree (dfs + 组合数)
    Hdu 5371 Hotaru's problem (manacher+枚举)
    Face The Right Way---hdu3276(开关问题)
  • 原文地址:https://www.cnblogs.com/zzqc/p/7395600.html
Copyright © 2011-2022 走看看