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语句!!!
  • 相关阅读:
    git命令大全
    QT学习笔记7:C++函数默认参数
    QT学习笔记6:常见的 QGraphicsItem
    QT学习笔记5:QMouseEvent鼠标事件简介
    QT学习笔记4:QT中GraphicsView编程
    QT学习笔记3:QT中语法说明
    Opencv学习笔记5:Opencv处理彩虹图、铜色图、灰度反转图
    Opencv学习笔记4:Opencv处理调整图片亮度和对比度
    deploy java web in IDEA with tomcat
    mongodb install
  • 原文地址:https://www.cnblogs.com/zzqc/p/7395600.html
Copyright © 2011-2022 走看看