---恢复内容开始---
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的最优解,然后暴力从后往前找就行。
大佬的代码总是那么的耐人寻味。