链接:https://ac.nowcoder.com/acm/contest/142/B
来源:牛客网
题目描述
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.
输入
2
2 4
1 2 2
3 4 5
1 4
1 3 1
输出
5
-1
题意:
给你n个带权区间,要求选择若干区间覆盖[1, m]内的所有整点,使得每个整点被覆盖权值和的最大值最小
思路:
可以猜一下:每个点最多被两个区间覆盖,那么就可以按照所有区间右端点排序,
然后设dp[i][x]为只考虑前i个区间,第i个区间必选,其中位置x处已经被两个区间所覆盖的最优解
直接n²暴力转移就好了
具体看代码,下面注释中有一个很强的样例
//https://ac.nowcoder.com/acm/contest/142/B
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
int dp[2005][2005];
typedef struct Res
{
int l, r, val;
bool operator < (const Res &b) const
{
if(r<b.r || r==b.r && l<b.l)
return 1;
return 0;
}
}Res;
Res s[2005];
int main(void)
{
int T, n, m, i, j, ans;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(i=0;i<=n;i++)
{
if(i!=0)
scanf("%d%d%d", &s[i].l, &s[i].r, &s[i].val);
for(j=0;j<=m;j++)
dp[i][j] = 1044266558;
}
sort(s+1, s+n+1);
dp[0][0] = 0;
for(i=1;i<=n;i++)
{
for(j=1;j<=i-1;j++)
{
if(s[j].r+1<s[i].l || s[j].l>=s[i].l)
continue;
if(s[j].r+1==s[i].l)
dp[i][s[j].r] = min(dp[i][s[j].r], max(dp[j][s[j].r], s[i].val));
else if(s[j].r+1>s[i].l)
dp[i][s[j].r] = min(dp[i][s[j].r], max(dp[j][s[i].l-1], s[i].val+s[j].val));
}
if(s[i].l==1)
dp[i][0] = s[i].val;
for(j=1;j<=s[i].r;j++)
dp[i][j] = min(dp[i][j], dp[i][j-1]);
}
ans = 1044266558;
for(i=1;i<=n;i++)
{
if(s[i].r==m)
ans = min(ans, dp[i][m]);
}
if(ans==1044266558)
printf("-1\n");
else
printf("%d\n", ans);
}
return 0;
}
/*
1
3 5
1 3 3
2 4 1
3 5 3
*/