Solution

A:Careful Thief

题意:给出n个区间,每个区间的每个位置的权值都是v,然后找长度为k的区间,使得这个区间的所有位置的权值加起来最大,输出最大权值, 所有区间不重叠

思路:贪心的想法,长度为k的区间的起始点肯定是某个区间的起始点,或者长度为k的区间的结束点肯定是某个区间的结束点。

因为存在最优的答案,它的起点不在某个区间的起点,那么只有两种情况。

1° 不属于任何已知区间

2° 在某个已知区间的内部

首先考虑第一种情况  如果不属于任何已知区间,那么根据贪心,我肯定能够往右移使得它是某个区间起点,这样得到的新的答案肯定大于等于原来的答案,因为我移动的这段区间的权值都为0

那么第二种情况,假如现在涵盖的区间横跨两个区间,那么我肯定能够右移结束点使得它与最后的那个区间的结束点对齐,或者左移起始点使得它跟最左边涵盖到的区间的起始点对齐,使得答案更大

然后双指针搞一搞

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define ll long long
 6 
 7 #define N 100010
 8 
 9 int t, m, k;
10 
11 struct node
12 {
13     int l, r;
14     ll v;
15     ll sum;
16     inline node() {}
17     inline node(int l, int r, int v) : l(l), r(r), v(v) {}
18     
19     inline void scan()
20     {
21         scanf("%d%d%lld", &l, &r, &v);
22         sum = (ll)(r - l + 1) * v;
23     }
24 
25     inline bool operator < (const node& b) const
26     {
27         return l < b.l;
28     }
29 }arr[N]; 
30 
31 int main()
32 {
33     scanf("%d", &t);
34     while (t--)
35     {
36         scanf("%d%d", &m, &k);
37         for (int i = 1; i <= m; ++i)
38             arr[i].scan();
39         
40         sort(arr + 1, arr + m + 1);        
41         int L, R;
42         int j = 1;
43         ll ans = 0;
44         ll tmp = 0;
45         for (int i = 1; i <= m; ++i)
46         {
47             L = arr[i].l; 
48             R = L + k - 1;
49             while (arr[j].r <= R && j <= m)
50             {
51                 tmp += arr[j].sum;
52                 ++j;    
53             }
54             ll res = 0;
55             if(j <= m)
56             {
57                 res = arr[j].v * max(0, R - arr[j].l + 1);
58             }
59             tmp += res;
60             ans = max(ans, tmp);
61             tmp -= res;
62             tmp -= arr[i].sum;
63         }
64         tmp = 0;
65         j = m;
66         for(int i = m; i >= 1; --i)
67         {
68             R = arr[i].r;
69             L = R - k + 1;
70             while(arr[j].l >= L && j >= 1)
71             {
72                 tmp += arr[j].sum;
73                 --j;
74             }
75             ll res = 0;
76             if(j >= 1)
77             {
78                 res = arr[j].v * max(0, arr[j].r - L + 1);
79             }
80             tmp += res;
81             ans = max(ans, tmp);
82             tmp -= res;
83             tmp -= arr[i].sum;
84         }
85         printf("%lld\n",ans);
86     }    
87     return 0;
88 }
View Code

相关文章: