Nowcoder-2018ACM多校訓練營(第四場)B Interval Revisited

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述 

Chiaki has a long interval [1,m] and n small intervals [l1, r1], [l2,r2], ..., [ln, rn]. Each small interval [li,ri] is associated with a weight wi.
Chiaki would to select some small intervals such that:

  • each integer position x ∈ [1, m] is covered by at least one small interval.
  • let sx be the sum of the weights of all the small intervals covering position x, the maximum value of sx should be minimum.

Chiaki would like to know the minimum value of maximum sx.

輸入描述:

There are multiple test cases. The first line of input contains an integer T, indicating the number of test
cases. For each test case:
The first line contains two integers n and m (1 ≤ n, m ≤ 2000) -- the number of small intervals and the length of the long interval.
Each of the next n lines contains three integers li, ri and wi (1 ≤ li ≤ ri ≤ m, 1 ≤ wi ≤ 1000).
It is guaranteed that the sum of all n does not exceed 20000.

輸出描述:

For each test case, output an integer denoting the answer, or -1 if Chiaki cannot select such intervals.

示例1

輸入

複製

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

輸出

複製

5
-1

題意:有n個線段,區間爲[L_{i},R_{i}],權值爲W_{i},用這些線段覆蓋[1,m]的區間,要求在使用的線段儘量少的前提下,區間上的點的權值的最大值儘可能的小,要求輸出最小權值

題解:考慮到每個點最多被2條線段覆蓋(如果被3條線段覆蓋,則一定可以刪除其中一條),我們可以這樣做:先將線段按照L升序排序,假設當前使用到了第i條線段,那麼是覆蓋了[1,R_{i}],假設最後一個被2條線段覆蓋的點的位置是j,那麼選擇下一條線段時,它的左端點L的範圍應該是[j + 1,R_{i}],這樣就可以進行DP了。

設dp[i][j]爲,當前使用到了第i條線段,下一條線段的下標至少從j開始,已經被覆蓋的點的最大權值

當R_{i} == m時,維護一下答案即可

#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define add(x,y) ((x)+(y))%mod
#define sub(x,y) ((x)-(y)+mod)%mod
#define mul(x,y) ((x)%mod)*((y)%mod)%mod
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
#define fuck(x) cout<<'['<<(x)<<']'<<endl;
using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 1000000007;
const int MX = 2e3 + 5;

int dp[MX][MX], t[MX];

struct node {
    int l, r, w;
    bool operator< (const node& _A) const {
        return l < _A.l;
    }
} a[MX];

int main() {
    //freopen ("in.txt", "r", stdin);
    int T, n, m; cin >> T;
    while (T--) {
        scanf ("%d%d", &n, &m);
        rep (i, 1, n + 1) scanf ("%d%d%d", &a[i].l, &a[i].r, &a[i].w);
        sort (a + 1, a + n + 1);
        rep (i, 1, n + 1) rep (j, 0, n + 2) dp[i][j] = INF;
        rep (i, 1, n + 1) {
            t[i] = n + 1;
            rep (j, i + 1, n + 1) if (a[j].l > a[i].r) {t[i] = j; break;}
        }
        int ans = INF;
        rep (i, 1, n + 1) {
            if (a[i].l == 1) dp[i][i + 1] = a[i].w;
            rep (j, i + 1, n + 1) {
                dp[i][j + 1] = min (dp[i][j + 1], dp[i][j]);
                if (a[j].l <= a[i].r) {
                    dp[j][t[i]] = min (dp[j][t[i]], max (dp[i][j], a[i].w + a[j].w) );
                }
                if (a[j].l == a[i].r + 1) {
                    dp[j][j + 1] = min (dp[j][j + 1], max (a[j].w, dp[i][j]) );
                }
            }
            if (a[i].r == m) ans = min (ans, dp[i][n + 1]);
        }
        cout << (ans == INF ? -1 : ans) << endl;
    }
    return 0;
}

 

發佈了291 篇原創文章 · 獲贊 104 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章