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语句!!!
原文地址:https://www.cnblogs.com/zzqc/p/7395600.html