牛客-肥猪-单调队列+环边链优化

---恢复内容开始---

 1 #include<bits/stdc++.h>
 2 #include<math.h>
 3 #include<map>
 4 #include<queue>
 5 #include<stack>
 6 #include<assert.h>
 7 #include <algorithm>
 8 #define ll long long
 9 using namespace std;
10 deque<int>que;
11 int arr[100005];
12 void push(int t){
13     while(!que.empty()&&arr[que.back()]>=arr[t]) que.pop_back();
14     que.push_back(t);
15 }
16 int main(){
17     int n,d;
18     scanf("%d %d",&n,&d);
19     for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
20     for(int i=n+1;i<=2*n;i++) arr[i]=arr[i-n];
21 //    for(int i=1;i<=2*n;i++) printf("%d ",arr[i]);
22 //    printf("\n");
23     ll sum=1e18;
24     for(int step=0;step<n;step++){
25         que.clear();
26         ll num=0;
27         for(int i=n+step;i>=n+1;i--) push(i);
28         //printf("%d %d\n",n+step,n+1);
29         for(int i=n;i>=1;i--){
30             push(i);
31             while(!que.empty()&&que.front()>i+step) que.pop_front();
32 //            printf(" %d %d\n",i,que.front());
33             num+=arr[que.front()];
34         }
35         sum=min(sum,num+(step*d));
36         //printf("%lld\n",sum);
37     }
38     printf("%lld\n",sum);
39     return 0;
40 }

把一个环变成链,将环部分复制到后面

1 2 3 4 5 

1 2 3 4 5 1 2 3 4 5

这样的话就好弄的多,具体为啥不清楚,反正就是把环变链,区间一段一段的往后,不用n%3啥的操作。

每一次都搞定一次循环中的step,由于是一个圈,一定能够有一个最小值来确定每一步的step的最优解,然后暴力从后往前找就行。

大佬的代码总是那么的耐人寻味。

猜你喜欢

转载自www.cnblogs.com/0123wtdd/p/10376695.html
今日推荐