Mowing the Lawn【线性dp + 单调队列优化】
标签:线性dp scanf www 选择 图片 优化 open hide back
题目链接:https://ac.nowcoder.com/acm/contest/2652/G
题目大意:与上一篇博客 烽火传递 差不多。
1.一共n头羊,若超过m头连续的羊在一起,就会集体罢工,每头羊有一个工作效率,求如何选择羊使得工作效率最高
题解思路:
1.我们可以转换思路,首先选择全部的羊,然后这是集体罢工,我们去拆分他们,即转换成了每连续的 m + 1头羊之间必须拆掉一头羊,则作为效率损失。
2.dp[i] 表示 拆掉第 i 只羊所造成的最小总损失。于是与烽火传递一样了。
3.该题还有一个注意的点是效率是1e9范围内,我们的inf不能开0x3f3f3f3f,不够大,需开 1ll
代码如下:
1 #include 2 #include 3 #include
4 typedef long long ll;
5 const int MAXN = 1e5 + 100;
6 using namespace std;
7 const ll inf = 1ll 62;
8
9 int n, m;
10 ll a[MAXN];
11 ll dp[MAXN]; //表示第 i 个烽火台放置烽火时的最小总代价
12 dequeint> Q;
13
14 int main()
15 {
16 ll sum = 0;
17 scanf("%d%d",&n, &m);
18 m ++;
19 for(int i = 1; i )
20 {
21 scanf("%lld", &a[i]);
22 sum += a[i];
23 }
24 for(int i = 1; i )
25 {
26 dp[i] = a[i];
27 while(!Q.empty())
28 {
29 if(dp[i] dp[Q.back()])
30 Q.pop_back();
31 else
32 break;
33 }
34 Q.push_back(i);
35 }
36 for(int i = m + 1; i )
37 {
38 while(!Q.empty())
39 {
40 if(i - m > Q.front())
41 Q.pop_front();
42 else
43 break;
44 }
45 dp[i] = dp[Q.front()] + a[i];
46 while(!Q.empty())
47 {
48 if(dp[i] dp[Q.back()])
49 Q.pop_back();
50 else
51 break;
52 }
53 Q.push_back(i);
54 }
55
56 ll minn = inf;
57 for(int i = n; i > n - m; i --)
58 minn = min(minn, dp[i]);
59 printf("%lld\n", sum - minn);
60 return 0;
61 }
62 /*
63 5 3
64 1 2 5 6 2
65
66 4
67 */
View Code
Mowing the Lawn【线性dp + 单调队列优化】
标签:线性dp scanf www 选择 图片 优化 open hide back
原文地址:https://www.cnblogs.com/yuanweidao/p/11931265.html
评论