题意 中文

可以先排序然后输出第k个 复杂度为O(N/*logN) 但有更快的方法 其实二分时只要能保证mid左边的数都比mid小 mid右边的数都比mid大就能进行划分了 对于k不在的区间就不用管了于是可以用到快排的思想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <cstdio>
using namespace std;
const int N = 1000005;
int a[N];
int main()
{
int n, k, l, r, le, ri, m;
while(~scanf("%d%d", &n, &k))
{
for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
if(n < k) {puts("-1"); continue;}
l = 0, r = n - 1;
while(l <= r)
{
m = a[le = l], ri = r;
while(le < ri)
{
while(le < ri && a[ri] > m) --ri;
a[le] = a[ri];
while(le < ri && a[le] < m) ++le;
a[ri] = a[le];
}
a[le] = m;
if(le < k - 1) l = le + 1;
else r = le - 1;
}
printf("%d\n", a[r + 1]);
}
return 0;
}

时间限制: 10000ms

单点时限: 1000ms
内存限制: 256MB

描述

在上一回里我们知道Nettle在玩《艦これ》,Nettle的镇守府有很多船位,但船位再多也是有限的。Nettle通过捞船又出了一艘稀有的船,但是已有的N(1≤N≤1,000,000)个船位都已经有船了。所以Nettle不得不把其中一艘船拆掉来让位给新的船。Nettle思考了很久,决定随机选择一个k,然后拆掉稀有度第k小的船。 已知每一艘船都有自己的稀有度,Nettle现在把所有船的稀有度值告诉你,希望你能帮他找出目标船。

提示:非有序数组的二分查找之二

输入

第1行:2个整数N,k。N表示数组长度,
第2行:N个整数,表示a[1..N],保证不会出现重复的数,1≤a[i]≤2,000,000,000。

输出

第1行:一个整数t,表示t在数组中是第k小的数,若K不在数组中,输出-1。
样例输入 10 4 1732 4176 2602 6176 1303 6207 3125 1 1011 6600 样例输出 1732

题意 你在一个n/*m个白色正方形格子组成的矩形的某个顶点格子 你沿着45度角的方向走 到了边界就改变方向90度 每次经过一个格子都改变他原来的颜(白或灰) 求你走到另一个顶点格子时矩形中有多少格子是灰色的

这题可以用公式也可以直接模拟 模拟就是一直向右移n-1位 每次超过边界就可以把边界向右移m-1位 用cnt记录超过边界的次数 那么每次都会经过cnt个已经走过的格子 (每个格子最多经过2次) 答案也就减去2/*cnt 直到刚好到达边界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n, m, cur, cnt, ans, k;
while(~scanf("%lld%lld", &n, &m))
{
if (n > m) swap(n, m);
cur = ans = 1, cnt = 0, k = m;
while(cur != k)
{
cur += n - 1, ans += n - 1 - 2 * cnt;
if(cur > k) k += m - 1, ++cnt;
}
printf("%lld\n", ans);
}
return 0;
}

Search for a Hiding-Place

Problem illustration

Scooby-Doo is fond of adventures. This time he wanted to find a hiding-place in a vampire castle. After a long search, Scooby ended up in a huge rectangular hall with four entrances, one in each corner, through one of which he had entered. The floor was paved with white square tiles. Scooby thought that the hiding-place was under one of these tiles. He started searching for it by turning the tiles over, the grey side up. He began his search from a corner moving at an angle of 45° to the walls. Each time he came to a wall, he made a 90° turn. If he stepped on a grey tile, he turned it back the white side up. The search went on until Scooby reached an entrance at one of the corners. Then, not having found the hiding-place, the tired dog sighed and went out to have a snack.
Given the dimensions of the hall, calculate the total number of tiles that were turned the grey side up at the end of the search.

The only input line contains integers n and m separated with a space. They are the length and width of the hall measured in tiles (2 ≤ n, m ≤ 1 000 000).

In the only line output the number of grey tiles in the hall after Scooby-Doo’s search.

input output 7 5 11 2 3 3

题意 给你一个城市的地图 你可以在地图上的 . 上建房子/#上不能建房子 红房子可以装200个人 蓝房子可以装100个人 只有相邻位置有蓝房子时才能建红房子 你也可以拆掉已经建成的房子 拆掉后该点又变成 .

这题想到了就很容易了 因为没有限制要步数最少 可以先把左右的地方都建成蓝房子 然后就变成求连通块的题了 每个蓝房子连通块内依次拆掉建红房子 最终就只剩下一个蓝房子了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
char g[N][N];
stack<pair<int, int> > s;
int x[] = { -1, 1, 0, 0};
int y[] = {0, 0, -1, 1};
int n, m, a, b, cnt, is_first;

int dfs(int i, int j)
{
int r, c;
if(is_first) is_first = 0;
else s.push(make_pair(i, j));
g[i][j] = 'R', cnt += 3;
for(int k = 0; k < 4; ++k)
{
r = i + x[k], c = j + y[k];
if(g[r][c] == '.') dfs(r, c);
}
}

int main()
{
while(~scanf("%d%d", &n, &m))
{
cnt = 0;
for(int i = 1; i <= n; ++i)
scanf("%s", g[i] + 1);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(g[i][j] == '.') is_first = 1, cnt -= 2, dfs(i, j);
printf("%d\n", cnt);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(g[i][j] != '#') printf("B %d %d\n", i, j);

while(!s.empty())
{
a = s.top().first, b = s.top().second;
printf("D %d %d\nR %d %d\n", a, b, a, b);
s.pop();
}
}
return 0;
}

Block Tower

After too much playing on paper, Iahub has switched to computer games. The game he plays is called “Block Towers”. It is played in a rectangular grid with n rows and m columns (it contains n × m cells). The goal of the game is to build your own city. Some cells in the grid are big holes, where Iahub can’t build any building. The rest of cells are empty. In some empty cell Iahub can build exactly one tower of two following types:

Iahub is also allowed to destroy a building from any cell. He can do this operation as much as he wants. After destroying a building, the other buildings are not influenced, and the destroyed cell becomes empty (so Iahub can build a tower in this cell if needed, see the second example for such a case).

Iahub can convince as many population as he wants to come into his city. So he needs to configure his city to allow maximum population possible. Therefore he should find a sequence of operations that builds the city in an optimal way, so that total population limit is as large as possible.

He says he’s the best at this game, but he doesn’t have the optimal solution. Write a program that calculates the optimal one, to show him that he’s not as good as he thinks.
Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 500). Each of the next n lines contains m characters, describing the grid. The j-th character in the i-th line is ‘.’ if you’re allowed to build at the cell with coordinates (i, j) a tower (empty cell) or ‘/#’ if there is a big hole there.

Output

Print an integer k in the first line (0 ≤ k ≤ 106) — the number of operations Iahub should perform to obtain optimal result.

Each of the following k lines must contain a single operation in the following format:

If there are multiple solutions you can output any of them. Note, that you shouldn’t minimize the number of operations.
Sample test(s)

input 2 3 ../# ./#.

output 4 B 1 1 R 1 2 R 2 1 B 2 3
input 1 3 …

output 5 B 1 1 B 1 2 R 1 3 D 1 2 R 1 2

题意 一条河两岸之间有n个石头 求取走m个石头后 使得两个石头间距离的最小值最大

感觉关键是理解题意 简单的二分 二分最小距离 看要取走多少个(cnt)石头 cnt<=m的话 说明最小距离还可以增大 这样就可以二分出答案了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 50005;
int p[N], l, n, m;

bool ok(int k)
{
int last = 0, cnt = 0;
for(int i = 1; i < n; ++i)
{
if(p[i] - p[last] < k) ++cnt;
else last = i;
}
return cnt <= m;
}

int main()
{
int le, ri, mid;
while(~scanf("%d%d%d", &l, &n, &m))
{
p[++n] = l;
for (int i = 1; i < n; ++i)
scanf("%d", &p[i]);

sort(p, p + n);
le = 0, ri = l;
while(le <= ri)
{
mid = (le + ri) >> 1;
if(ok(mid)) le = mid + 1;
else ri = mid - 1;
}
printf("%d\n", le - 1);
}
return 0;
}

River Hopscotch

Description
Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 ≤ L ≤ 1,000,000,000). Along the river between the starting and ending rocks, N (0 ≤N ≤ 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L).

To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river.

Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to Mrocks (0 ≤ MN).

FJ wants to know exactly how much he can increase the shortest distance /before/ he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks.

Input

Line 1: Three space-separated integers: L, N, and M
Lines 2.. N+1: Each line contains a single integer indicating how far some rock is away from the starting rock. No two rocks share the same position.

Output

Line 1: A single integer that is the maximum of the shortest distance a cow has to jump after removing M rocks

Sample Input

25 5 2 2 14 11 21 17

Sample Output

4

Hint

Before removing any rocks, the shortest jump was a jump of 2 from 0 (the start) to 2. After removing the rocks at 2 and 14, the shortest required jump is a jump of 4 (from 17 to 21 or from 21 to 25).

Source

USACO 2006 December Silver

题意 你在KTV还剩t秒钟的时间 你需要在n首歌中选择尽量多的歌使得歌的数量最多的前提下剩下的时间最小

至少要留一秒给劲歌金曲 所以是一个容量为t-1的01背包 d[i][j]表示恰用j秒时间在前i首歌中最多唱多少首 每个状态有两种选择 唱或不唱第i首歌

所以有转移方程d[i][j]=max(d[i-1][j],d[i-1][j-c[i]]+1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 180;
int c[N], d[N * M], t, n;

int main()
{
int cas, ans;
scanf("%d", &cas);
for(int k = 1; k <= cas; ++k)
{
memset(d, 0x8f, sizeof(d));
scanf("%d%d", &n, &t);
for(int i = 0; i < n; ++i) scanf("%d", &c[i]);
d[0] = 0;
for(int i = 0; i < n; ++i)
for(int j = t - 1; j >= c[i]; --j)
d[j] = max(d[j], d[j - c[i]] + 1);
for(int j = ans = t - 1; j >= 0; --j) if(d[j] > d[ans]) ans = j;
printf("Case %d: %d %d\n", k, d[ans] + 1, ans + 678);
}
return 0;
}

题意 一个n/*m的环形矩阵(第一行和最后一行是相邻的) 从第一列任意位置出发 只能往右上,右,右下3个方向走 求走到第m列经过的的最小数字和

基础DP 横着的数塔问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
#define l(x) d[x][j+1]
using namespace std;
const int N = 105;
int n, m, g[N][N], d[N][N], fol[N][N];
int main()
{
int n, m, u, b, t, k;
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
scanf("%d", &g[i][j]);

memset(d, 0x3f, sizeof(d));
for(int i = 0; i < n; ++i) d[i][m - 1] = g[i][m - 1];
for(int j = m - 2; j >= 0; --j)
{
for(int i = 0; i < n; ++i)
{
u = (i + n - 1) % n, b = (i + 1) % n, t = i;
if(l(u) < l(t) || (l(u) == l(t) && u < t)) t = u;
if(l(b) < l(t) || (l(b) == l(t) && b < t)) t = b;
d[i][j] = g[i][j] + d[t][j + 1], fol[i][j] = t;
}
}

for(int i = k = 0; i < n; ++i)
if(d[i][0] < d[k][0] || (d[i][0] == d[k][0] && i < k)) k = i;
int ans = d[k][0];
for(int j = 0; j < m - 1; ++j) printf("%d ", k + 1), k = fol[k][j];
printf("%d\n%d\n", k + 1, ans);
}
return 0;
}


Background

Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Traveling Salesperson Problem (TSP) – finding whether all the cities in a salesperson’s route can be visited exactly once with a specified limit on travel time – is one of the canonical examples of an NP-complete problem; solutions appear to require an inordinate amount of time to generate, but are simple to check.

This problem deals with finding a minimal path through a grid of points while traveling only from left to right.

The Problem

Given an tex2html_wrap_inline352 matrix of integers, you are to write a program that computes a path of minimal weight. A path starts anywhere in column 1 (the first column) and consists of a sequence of steps terminating in column n (the last column). A step consists of traveling from column i to column i+1 in an adjacent (horizontal or diagonal) row. The first and last rows (rows 1 and m) of a matrix are considered adjacent, i.e., the matrix ``wraps’’ so that it represents a horizontal cylinder. Legal steps are illustrated below.

picture25

The weight of a path is the sum of the integers in each of the n cells of the matrix that are visited.

For example, two slightly different tex2html_wrap_inline366 matrices are shown below (the only difference is the numbers in the bottom row).

picture37

The minimal path is illustrated for each matrix. Note that the path for the matrix on the right takes advantage of the adjacency property of the first and last rows.

The Input

The input consists of a sequence of matrix specifications. Each matrix specification consists of the row and column dimensions in that order on a line followed by tex2html_wrap_inline376 integers where m is the row dimension and n is the column dimension. The integers appear in the input in row major order, i.e., the first n integers constitute the first row of the matrix, the second n integers constitute the second row and so on. The integers on a line will be separated from other integers by one or more spaces. Note: integers are not restricted to being positive. There will be one or more matrix specifications in an input file. Input is terminated by end-of-file.

For each specification the number of rows will be between 1 and 10 inclusive; the number of columns will be between 1 and 100 inclusive. No path’s weight will exceed integer values representable using 30 bits.

The Output

Two lines should be output for each matrix specification in the input file, the first line represents a minimal-weight path, and the second line is the cost of a minimal path. The path consists of a sequence of n integers (separated by one or more spaces) representing the rows that constitute the minimal path. If there is more than one path of minimal weight the path that islexicographically smallest should be output.

Sample Input

5 6 3 4 1 2 8 6 6 1 8 2 7 4 5 9 3 9 9 5 8 4 1 3 2 6 3 7 2 8 6 4 5 6 3 4 1 2 8 6 6 1 8 2 7 4 5 9 3 9 9 5 8 4 1 3 2 6 3 7 2 1 2 3 2 2 9 10 9 10

Sample Output

1 2 3 4 4 5 16 1 2 1 5 4 5 11 1 1 19

题意 二维坐标系上有n个点 从第一个点出发经过部分点到达第n个点 再从第n个点回到第一个点 除了第一个点 每个点都经过且仅经过一次 求最短路径长度

还是基础的DP 想出状态转移方程就容易了 d[i][j]表示去的时候经过第i个点回来经过第j个点且1~max(i,j)间的点都已经走过 显然d[i][j]=d[j][i] 所以只用考虑i>j的部分 i<j的部分d[i][j]保存i,j两点之间的距离

第i+1个点要么去的时候走 要么回来的时候走

  1. 去的时候走d[i+1][i] + d[i][i+1],d[i][i+1]保存的是距离

  2. 回来的时候走**d[i+1][j] + d[j][i+1].****d[i][i+1]**保存的是距离

所以有状态转移方程d[i][j] = min(d[i+1][i] + d[i][i+1],d[i+1][j] + d[j][j+1]).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
#define l(x) (x[i]-x[j])*(x[i]-x[j])
using namespace std;
const int N = 105;
int x[N], y[N];
double d[N][N];

int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; ++i)
{
scanf("%d%d", &x[i], &y[i]);
for(int j = 1; j < i; ++j)
d[j][i] = sqrt(l(x) + l(y));
}

for(int i = 1; i < n - 1; ++i) d[n - 1][i] = d[n - 1][n] + d[i][n];
for(int i = n - 2; i > 1; --i)
{
for(int j = 1; j < i; ++j)
d[i][j] = min(d[i + 1][j] + d[i][i + 1], d[i + 1][i] + d[j][i + 1]);
}
printf("%.2lf\n", d[1][2] + d[2][1]);
}
return 0;
}

John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John must determine the shortest closed tour that connects his destinations. Each destination is represented by a point in the plane pi = < *x*i, *y*i > . John uses the following strategy: he starts from the leftmost point, then he goes strictly left to right to the rightmost point, and then he goes strictly right back to the starting point. It is known that the points have distinct x -coordinates.

Write a program that, given a set of n points in the plane, computes the shortest closed tour that connects the points according to John’s strategy.

The program input is from a text file. Each data set in the file stands for a particular set of points. For each set of points the data set contains the number of points, and the point coordinates in ascending order of the x coordinate. White spaces can occur freely in input. The input data are correct.

For each set of data, your program should print the result to the standard output from the beginning of a line. The tour length, a floating-point number with two fractional digits, represents the result.

Note: An input/output sample is in the table below. Here there are two data sets. The first one contains 3 points specified by their x and y coordinates. The second point, for example, has the xcoordinate 2, and the y coordinate 3. The result for each data set is the tour length, (6.47 for the first data set in the given example).

3 1 1 2 3 3 1 4 1 1 2 3 3 1 4 2

6.47 7.89


题意 某城市的地铁有n个车站 编号1到n 有m1辆车向右开 给出m1个从车站1出发的时间 m2辆车向左开 给出m2个从车站n出发的时间 t[i]为火车从第i个车站开到第i+1(或相反)个车站需要的时间 Maria在车站1 她需要恰在时刻T到达第n个车站 求她的最小总车站等待时间

基础的多阶段决策DP 令d[i][j]表示时刻j在i号车站剩下的最小总等待时间 每种状态有3种选择

  1. 等一个单位时间d[i][j+1]+1;

  2. 当前站此时有往左的车并搭乘d[i-1][j+t[i-1]];

3.当前站此时有往右的车并搭乘d[i+1][j+t[i]].

每个点三种选择选最优的就行了 边界条件为d[n][T]=0 其它状态均初始化为INF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 205;
int t[N], d[N][M]; //j时刻在i号车站剩下的最小总等待时间
bool l[N][M], r[N][M]; //j时刻在i号车站是否有往左(右)的车

int main()
{
int n, m, ti, cur, cas = 0;

while(~scanf("%d", &n), n)
{
scanf("%d", &ti);
memset(l, 0, sizeof(l)), memset(r, 0, sizeof(r));
for(int i = 1; i < n; ++i) scanf("%d", &t[i]);

scanf("%d", &m); //cur时刻车站j是否有往右的车
for(int i = 1; i <= m; ++i)
{
scanf("%d", &cur);
for(int j = 1; j <= n; ++j)
r[j][cur] = 1, cur += t[j];
}
scanf("%d", &m); //cur时刻车站j是否有往左的车
for(int i = 1; i <= m; ++i)
{
scanf("%d", &cur);
for(int j = n; j >= 1; --j)
l[j][cur] = 1, cur += t[j - 1];
}

memset(d, 0x3f, sizeof(d));
d[n][ti] = 0;
for(int j = ti - 1; j >= 0; --j)
{
for(int i = 1; i <= n; ++i)
{
d[i][j] = d[i][j + 1] + 1; //在i车站等1单位时间
if(l[i][j]) d[i][j] = min(d[i][j], d[i - 1][j + t[i - 1]]); //往左
if(r[i][j]) d[i][j] = min(d[i][j], d[i + 1][j + t[i]]); //往右
}
}

printf("Case Number %d: ", ++cas);
if(d[1][0] > ti) puts("impossible");
else printf("%d\n", d[1][0]);
}
return 0;
}

Secret agent Maria was sent to Algorithms City to carry out an especially dangerous mission. After several thrilling events we find her in the first station of Algorithms City Metro, examining the time table. The Algorithms City Metro consists of a single line with trains running both ways, so its time table is not complicated.

Maria has an appointment with a local spy at the last station of Algorithms City Metro. Maria knows that a powerful organization is after her. She also knows that while waiting at a station, she is at great risk of being caught. To hide in a running train is much safer, so she decides to stay in running trains as much as possible, even if this means traveling backward and forward. Maria needs to know a schedule with minimal waiting time at the stations that gets her to the last station in time for her appointment. You must write a program that finds the total waiting time in a best schedule for Maria.

The Algorithms City Metro system has N stations, consecutively numbered from 1 to N. Trains move in both directions: from the first station to the last station and from the last station back to the first station. The time required for a train to travel between two consecutive stations is fixed since all trains move at the same speed. Trains make a very short stop at each station, which you can ignore for simplicity. Since she is a very fast agent, Maria can always change trains at a station even if the trains involved stop in that station at the same time.

\epsfbox{p2728.eps}

The input file contains several test cases. Each test case consists of seven lines with information as follows. Line 1. The integer N ( 2$ \le$N$ \le$50), which is the number of stations. Line 2. The integer T ( 0$ \le$T$ \le$200), which is the time of the appointment. Line 3. N - 1 integers: t1, t2,…, tN - 1 ( 1$ \le$ti$ \le$70), representing the travel times for the trains between two consecutive stations: t1 represents the travel time between the first two stations, t2 the time between the second and the third station, and so on. Line 4. The integer M1 ( 1$ \le$M1$ \le$50), representing the number of trains departing from the first station. Line 5. M1 integers: d1, d2,…, dM1 ( 0$ \le$di$ \le$250 and di < di + 1), representing the times at which trains depart from the first station. Line 6. The integer M2 ( 1$ \le$M2$ \le$50), representing the number of trains departing from the N-th station. Line 7. M2 integers: e1, e2,…, eM2 ( 0$ \le$ei$ \le$250 and ei < ei + 1) representing the times at which trains depart from the N-th station.

The last case is followed by a line containing a single zero.

For each test case, print a line containing the case number (starting with 1) and an integer representing the total waiting time in the stations for a best schedule, or the word ` impossible ‘ in case Maria is unable to make the appointment. Use the format of the sample output.

4 55 5 10 15 4 0 5 10 20 4 0 5 10 15 4 18 1 2 3 5 0 3 6 10 12 6 0 3 5 7 12 15 2 30 20 1 20 7 1 3 5 7 11 13 17 0

Case Number 1: 5 Case Number 2: 0 Case Number 3: impossible

题意 把m数分成k组 使每组数的和的最大值最小 如果有多种分法 靠前的组的和尽量小

关键是找出那个最小的最大值 可以通过二分来找出 开始左端点为m个数中最大的数 右端点为m个数的和 若中点能将m个数分为小于等于k组 比它大的肯定都是可以的 中点变为右端点 否则中点变成左端点

然后就可以贪心逆向模拟了 从后往前每组选择尽量多的数直到剩下的数等于组数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 505;
int a[N], d[N], m, k, maxi;
ll s[N], le, ri, mid, mins, t;

int divs()
{
int last = 0, cnt = 1;
for(int i = 1; i <= m; ++i)
{
if(s[i] - s[last] > mid)
last = i - 1, ++cnt;
}
return cnt;
}

int main()
{
int cas;
scanf("%d", &cas);
while(cas--)
{
scanf("%d %d", &m, &k);
for(int i = maxi = 1; i <= m; ++i)
{
scanf("%d", &a[i]);
s[i] = s[i - 1] + a[i];
if(a[i] > a[maxi]) maxi = i;
}

le = a[maxi], ri = s[m];
while(le <= ri)
{
mid = (le + ri) >> 1;
if(divs() <= k) mins = mid, ri = mid - 1;
else le = mid + 1;
}

t = 0;
memset(d, 0, sizeof(d));
for(int i = m; i > 0; --i)
{
if(t + a[i] > mins)
d[i] = k--, t = 0;
if(k >= i) while(i > 0) d[--i] = 1;
t = t + a[i];
}

for(int i = 1; i <= m; ++i)
{
printf("%d%c", a[i], i < m ? ' ' : '\n');
if(d[i]) printf("/ ");
}
}
return 0;
}


Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most famous scribers lived in the 15th century and his name was Xaverius Endricus Remius Ontius Xendrianus (Xerox). Anyway, the work was very annoying and boring. And the only way to speed it up was to hire more scribers.

Once upon a time, there was a theater ensemble that wanted to play famous Antique Tragedies. The scripts of these plays were divided into many books and actors needed more copies of them, of course. So they hired many scribers to make copies of these books. Imagine you have m books (numbered $1, 2, \dots, m$) that may have different number of pages ( $p_1, p_2, \dots, p_m$) and you want to make one copy of each of them. Your task is to divide these books among k scribes, $k \le m$. Each book can be assigned to a single scriber only, and every scriber must get a continuous sequence of books. That means, there exists an increasing succession of numbers $0 = b_0 <b_1 < b_2, \dots < b_{k-1} \le b_k = m$such that i-th scriber gets a sequence of books with numbers between b**i-1+1 and b**i. The time needed to make a copy of all the books is determined by the scriber who was assigned the most work. Therefore, our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly two lines. At the first line, there are two integersm and k, $1 \le k \le m \le 500$. At the second line, there are integers $p_1, p_2, \dots p_m$ separated by spaces. All these values are positive and less than 10000000.

For each case, print exactly one line. The line must contain the input succession $p_1, p_2, \dots p_m$divided into exactly k parts such that the maximum sum of a single part should be as small as possible. Use the slash character (`/‘) to separate the parts. There must be exactly one space character between any two successive numbers and between the number and the slash.

If there is more than one solution, print the one that minimizes the work assigned to the first scriber, then to the second scriber etc. But each scriber must be assigned at least one book.

2 9 3 100 200 300 400 500 600 700 800 900 5 4 100 100 100 100 100

100 200 300 400 500 / 600 700 / 800 900 100 / 100 / 100 / 100 100


Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most famous scribers lived in the 15th century and his name was Xaverius Endricus Remius Ontius Xendrianus (Xerox). Anyway, the work was very annoying and boring. And the only way to speed it up was to hire more scribers.

Once upon a time, there was a theater ensemble that wanted to play famous Antique Tragedies. The scripts of these plays were divided into many books and actors needed more copies of them, of course. So they hired many scribers to make copies of these books. Imagine you have m books (numbered $1, 2, \dots, m$) that may have different number of pages ( $p_1, p_2, \dots, p_m$) and you want to make one copy of each of them. Your task is to divide these books among k scribes, $k \le m$. Each book can be assigned to a single scriber only, and every scriber must get a continuous sequence of books. That means, there exists an increasing succession of numbers '$0 = b_0 <such that i-th scriber gets a sequence of books with numbers between b**i-1+1 and b**i. The time needed to make a copy of all the books is determined by the scriber who was assigned the most work. Therefore, our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly two lines. At the first line, there are two integersm and k, $1 \le k \le m \le 500$. At the second line, there are integers $p_1, p_2, \dots p_m$ separated by spaces. All these values are positive and less than 10000000.

For each case, print exactly one line. The line must contain the input succession $p_1, p_2, \dots p_m$divided into exactly k parts such that the maximum sum of a single part should be as small as possible. Use the slash character (`/‘) to separate the parts. There must be exactly one space character between any two successive numbers and between the number and the slash.

If there is more than one solution, print the one that minimizes the work assigned to the first scriber, then to the second scriber etc. But each scriber must be assigned at least one book.

2 9 3 100 200 300 400 500 600 700 800 900 5 4 100 100 100 100 100

100 200 300 400 500 / 600 700 / 800 900 100 / 100 / 100 / 100 100

题意 有n个村庄 第i个村庄需要买a[i]的酒 a[i]为负时该村庄可卖掉-a[i]的酒 保证所有a[i]的和为0 一个单位的酒从一个村庄运输到相邻村庄的消耗为1 求运输完所有酒需要的最小消耗

总消耗最少时 每个需要买的村庄都会找离他最近的可以卖的村庄 容易发现 这种状况下 从第一个村和第二个村庄之间的运输量为abs(a[1]) 第二个村庄和第三个村庄之间的运输量为abs(a[1]+a[2]) 第k个村庄到第k+1个村庄的运输量为abs(a[1]+a[2]+…+a[k])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, t;
long long ans, last;
while(~scanf("%d", &n), n)
{
ans = last = 0;
//last记录需要从i-1运输到i的量
for(int i = 1; i <= n; ++i)
{
scanf("%d", &t);
ans += abs(last), last += t;
}
printf("%lld\n", ans);
}
return 0;
}

Wine trading in Gergovia

As you may know from the comic “Asterix and the Chieftain’s Shield”, Gergovia consists of one street, and every inhabitant of the city is a wine salesman. You wonder how this economy works? Simple enough: everyone buys wine from other inhabitants of the city. Every day each inhabitant decides how much wine he wants to buy or sell. Interestingly, demand and supply is always the same, so that each inhabitant gets what he wants.

There is one problem, however: Transporting wine from one house to another results in work. Since all wines are equally good, the inhabitants of Gergovia don’t care which persons they are doing trade with, they are only interested in selling or buying a specific amount of wine. They are clever enough to figure out a way of trading so that the overall amount of work needed for transports is minimized.

In this problem you are asked to reconstruct the trading during one day in Gergovia. For simplicity we will assume that the houses are built along a straight line with equal distance between adjacent houses. Transporting one bottle of wine from one house to an adjacent house results in one unit of work.

Input Specification

The input consists of several test cases. Each test case starts with the number of inhabitants n (2 ≤ n ≤ 100000). The following line contains n integers ai (-1000 ≤ ai ≤ 1000). If ai ≥ 0, it means that the inhabitant living in the ith house wants to buy ai bottles of wine, otherwise if ai < 0, he wants to sell -ai bottles of wine. You may assume that the numbers ai sum up to 0.
The last test case is followed by a line containing 0.

Output Specification

For each test case print the minimum amount of work units needed so that every inhabitant has his demand fulfilled. You may assume that this number fits into a signed 64-bit integer (in C/C++ you can use the data type “long long”, in JAVA the data type “long”).

Sample Input

5 5 -4 1 -3 1 6 -1000 -1000 -1000 1000 1000 1000 0

Sample Output

9 9000

0%