一个二位平面上有n个垃圾,现在用一个机器人去捡起来,且是按照输入顺序捡,放回位于原点处的垃圾桶中,两点之间的距离算曼哈顿距离,机器人的最大承重量为C,求捡完所有垃圾机器人走动的最小距离。
sumdis[i], sum weight[i]都表示前缀和。
dp[i]表示第i个捡完时的最小距离。
考虑某次见掉i与j之间的所有垃圾。
dp[i] = min{dp[i], dp[j-1] + sumdis[i] - sumdis[j] + dis[j] + dis[i]} && sumweight[i] - sumweight[j - 1] <= c;
dp[n]就是最后的结果。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back #define lson rt << 1 #define rson rt << 1 | 1 #define bug cout << "BUG HERE\n" typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int nCase = 0; const int maxn = 100010; int n, c; int sumdis[maxn], sumweight[maxn]; int dp[maxn]; struct Node { int x, y, w; }a[maxn]; int getdis(int i,int j) { return abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t; scanf("%d",&t); while(t--) { scanf("%d%d",&c,&n); if (nCase) puts(""); nCase++; for (int i = 1;i <= n;++i) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); sumdis[i] = sumdis[i - 1] + getdis(i, i - 1); sumweight[i] = sumweight[i - 1] + a[i].w; } for (int i = 1;i <= n;++i) { dp[i] = INF; for (int j = i;j >= 1;--j) { int w = sumweight[i] - sumweight[j - 1]; if (w > c) break; int dis = getdis(0, j) + sumdis[i] - sumdis[j] + getdis(0, i); dp[i] = min(dp[i], dp[j - 1] + dis); } } printf("%d\n", dp[n]); } return 0; }