2014
02-27

# Group Travel

After finished the composition exam of GRE, Sigma and QK wanted to have a good rest, and then invented all member of ACM-BUAA team to go to a trip. After some hard work, they find a bus for vehicle in the trip.

Unfortunately, not all the people in ACM-BUAA team want to go to the same place, so the bus must parking at some place. But as we know, the traffic is always bad, so they decided only parking on some place.

You can assume all where they want to go is on positive number axis, and Beihang University is on the origin. There are N people on the ACM-BUAA team. The ith people want to the place pi. For some reason, they didn’t want the number of parking times exceed K.

Because all of them are busy preparing the trip, when they realize the parking-problem, it’s too late for them to coding. So they ask you for help, can you minimize the sum of the walking distance for all the people?

Input includes multiple cases.

First line is the number of case t.

For each case: The first line contain two integer number N,K (0<K<=N<=3000). The second line contains N numbers, which means pi(0<=pi<=10^5) mentioned before.

Input includes multiple cases.

First line is the number of case t.

For each case: The first line contain two integer number N,K (0<K<=N<=3000). The second line contains N numbers, which means pi(0<=pi<=10^5) mentioned before.

2
3 1
1 11 21
6 2
1 2 4 11 12 14

20
6

HDU_3053

这个题目和POJ_1160几乎是一样的，具体的一些思路可以参考我的POJ_1160的题解：http://www.cnblogs.com/staginner/archive/2012/03/12/2391925.html?updated=1。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXD 3010
#define INF 0x3f3f3f3f
int N, P, f[MAXD][MAXD], K[MAXD][MAXD], A[MAXD], a[MAXD];
void init()
{
int i;
scanf("%d%d", &N, &P);
for(i = 1; i <= N; i ++) scanf("%d", &a[i]);
std::sort(a + 1, a + 1 + N);
for(i = 1, A[0] = 0; i <= N; i ++) A[i] = A[i - 1] + a[i];
}
int getw(int x, int y)
{
int t = x + y >> 1;
return (t - x) * a[t] - A[t - 1] + A[x - 1] + A[y] - A[t] - (y - t) * a[t];
}
void solve()
{
int i, j, k, p, t;
for(i = 0; i <= N; i ++) K[i][i] = i, f[i][i] = 0;
for(p = 1; p <= N - P; p ++)
{
for(i = 0; (j = i + p) <= N; i ++) f[i][j] = INF;
for(i = 1; (j = i + p) <= N; i ++)
for(k = K[i][j - 1]; k <= K[i + 1][j]; k ++)
if(f[i][j] > (t = f[i - 1][k - 1] + getw(k, j)))
f[i][j] = t, K[i][j] = k;
}
printf("%d\n", f[P][N]);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
if(P >= N) printf("0\n");
else solve();
}
return 0;
}

1. 约瑟夫也用说这么长……很成熟的一个问题了，分治的方法解起来o(n)就可以了，有兴趣可以看看具体数学的第一章，关于约瑟夫问题推导出了一系列的结论，很漂亮

2. 第一句可以忽略不计了吧。从第二句开始分析，说明这个花色下的所有牌都会在其它里面出现，那么还剩下♠️和♦️。第三句，可以排除2和7，因为在两种花色里有。现在是第四句，因为♠️还剩下多个，只有是♦️B才能知道答案。