O(n^2)代码:
#define CLEAR(a) memset((a),0,sizeof((a)))
const int maxn=1e5+10;
const int inf=1<<30;
struct Point
{
int x,y;
Point(){x=0;y=0;};
Point(int x,int y){this->x=x;this->y=y;};
} point[maxn];
int w[maxn];
typedef pair<int,int> pr;
int disp(Point p1,Point p2)
{
return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
int f[maxn];
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
CLEAR(f);CLEAR(w);
int n,c;
scanf("%d%d",&c,&n);
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d%d",&x,&y,&w[i]);
point[i]=Point(x,y);
}
f[0]=0;
//f[1]=2*disp(point[0],point[1]);
for(int i=1;i<=n;++i)//若为i++,应如何修改?
{
int sw=w[i],d=disp(point[0],point[i]);
f[i]=inf;
for(int j=i-1;sw<=c&&j>=0;--j)//若为j--,应如何修改?
{
f[i]=min(f[i],f[j]+d+disp(point[0],point[j+1]));
sw+=w[j];d+=disp(point[j],point[j+1]);
}
//cout<<f[i]<<endl;
}
printf("Case %d: %d\n",++kase,f[n]);
}
return 0;
}
单调队列优化,状态转移方程做了一些调整
#define CLEAR(a) memset((a),0,sizeof((a)))
typedef long long LL;
const int maxn=1e5+10;
const int inf=1<<30;
struct Point
{
int x,y;
Point(){x=0;y=0;};
Point(int x,int y){this->x=x;this->y=y;};
} point[maxn];
struct pr
{
LL first,second;
pr(){};
pr(int a,int b):first(a),second(b){};
bool operator< (const pr &a) const
{
if (second==a.second) return first>a.first;
else return second>a.second;
}
};
LL disp(Point p1,Point p2)
{
return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
LL f[maxn],s[maxn],sw[maxn],w[maxn];
template <class T>
class Priority_Queue
{
private:
T qnode[maxn];
int head,rear;
public:
Priority_Queue()
{
head=rear=0;
};
bool empty()
{
return head==rear;
}
T top()
{
return qnode[head];
};
void pop()
{
if (head<rear) head++;
}
void pop(int id,int c)
{
while ( head < rear && sw[id] - sw[qnode[head].first-1] > c ) head++;
}
void push(T node)
{
while (rear > head && qnode[rear - 1].second > node.second)
{
rear--;
}
qnode[rear++]=node;
}
};
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
CLEAR(f);CLEAR(s);CLEAR(sw);
int n,c;
scanf("%d%d",&c,&n);
bool reach=1;
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d%lld",&x,&y,&w[i]);
if (w[i]>c) reach=0;
point[i]=Point(x,y);
sw[i]=sw[i-1]+w[i];
s[i]=s[i-1]+disp(point[i-1],point[i]);
}
f[0]=0;
Priority_Queue<pr> q;
//q.push(pr(0,0));
for(int i=1;i<=n;++i)
{
LL d=disp(point[0],point[i]);
q.push(pr(i,f[i-1]-s[i]+d));
q.pop(i,c);
pr k=q.top();
f[i]=k.second+s[i]+d;
//cout<<f[i]<<endl;
}
if (reach) printf("%lld\n",f[n]);
else printf("0\n");
}
return 0;
}