[Codeforces 1579G] Minimal Coverage | dp最小区间覆盖

Posted PushyTao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces 1579G] Minimal Coverage | dp最小区间覆盖相关的知识,希望对你有一定的参考价值。

You are given n lengths of segments that need to be placed on an infinite axis with coordinates.

The first segment is placed on the axis so that one of its endpoints lies at the point with coordinate 0. Let’s call this endpoint the “start” of the first segment and let’s call its “end” as that endpoint that is not the start.

The “start” of each following segment must coincide with the “end” of the previous one. Thus, if the length of the next segment is d and the “end” of the previous one has the coordinate x, the segment can be placed either on the coordinates [x−d,x], and then the coordinate of its “end” is x−d, or on the coordinates [x,x+d], in which case its “end” coordinate is x+d.

The total coverage of the axis by these segments is defined as their overall union which is basically the set of points covered by at least one of the segments. It’s easy to show that the coverage will also be a segment on the axis. Determine the minimal possible length of the coverage that can be obtained by placing all the segments on the axis without changing their order.

Input
The first line contains an integer t ( 1 ≤ t ≤ 1000 ) (1≤t≤1000) (1t1000) — the number of test cases.

The next 2t lines contain descriptions of the test cases.

The first line of each test case description contains an integer n ( 1 ≤ n ≤ 1 0 4 ) (1≤n≤10^4) (1n104) — the number of segments. The second line of the description contains n space-separated integers a i ( 1 ≤ a i ≤ 1000 ) a_i (1≤a_i≤1000) ai(1ai1000) — lengths of the segments in the same order they should be placed on the axis.

It is guaranteed that the sum of n over all test cases does not exceed 1 0 4 10^4 104.

Output
Print t lines, each line containing the answer to the corresponding test case. The answer to a test case should be a single integer — the minimal possible length of the axis coverage.

Example
inputCopy

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

outputCopy

3
3
9
9
7
8

Note
In the third sample test case the segments should be arranged as follows: [0,6]→[4,6]→[4,7]→[−2,7]. As you can see, the last segment [−2,7] covers all the previous ones, and the total length of coverage is 9.

In the fourth sample test case the segments should be arranged as [0,6]→[−2,6]→[−2,2]→[2,7]. The union of these segments also occupies the area [−2,7] and has the length of 9.

题意:
给出n个线段,以及一个无限大的坐标轴,第一个线段以0为起点进行放置,后面的线段必须以前一个的终点为起点放置,这就有两种方式,向左向右
用memset会被卡TLE,所以说尽量还是手动 f o r for for来进行初始化
d p [ i ] [ j ] dp[i][j] dp[i][j]是前 i i i个线段以轴上一点 j j j为终点的覆盖长度大小
因为可能出现直接向左进行放的情况,所以说左边的点可能会出现负数,这里可以进行偏移一点
枚举 n n n个线段,每个线段的长度为 a [ i ] a[i] a[i]
然后枚举终点坐标j{
向左放置:
if(j<=a[i]) dp[i][0] = min(dp[i][0],dp[i-1][j]+a[i]-j);
else dp[i][j-a[i]] = min(dp[i][j-a[i]],dp[i-1][j]
向右放置:
dp[i][j+a[i]] = min( dp[i][j+a[i]],
max(dp[i-1][j],a[i]+j)
)
}

int n;
int a[10007];
int dp[10007][2001];
int main() {
  int _ = read;
  while (_--) {
    n = read;
    for (int i = 1; i <= n; i++) a[i] = read;
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= 2000; j++) dp[i][j] = 0x3f3f3f3f;
    }
    dp[0][0] = 0LL;
    for (int i = 1; i <= n; i++) {
      for (int j = 0; j <= 2000; j++) {
        if (j <= a[i])
          dp[i][0] = min(dp[i][0], dp[i - 1][j] + a[i] - j);
        else
          dp[i][j - a[i]] = min(dp[i][j - a[i]], dp[i - 1][j]);
        dp[i][j + a[i]] = min(dp[i][j + a[i]], max(dp[i - 1][j], a[i] + j));
      }
    }
    int ans = 0x3f3f3f3f;
    for (int i = 0; i <= 2000; i++) {
      ans = min(ans, dp[n][i]);
    }
    printf("%d\\n", ans);
  }
  return 0;
}

以上是关于[Codeforces 1579G] Minimal Coverage | dp最小区间覆盖的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 1579G Minimal Coverage(dp)

CodeForces - 1579G Minimal Coverage(dp)

Minima黑色响应式后台管理模板

Minima黑色响应式后台管理模板

P3507 [POI2010]GRA-The Minima Game

洛谷 P3507 [POI2010]GRA-The Minima Game