1. 程式人生 > >Codeforces Round #466 (Div. 2) ---e

Codeforces Round #466 (Div. 2) ---e

lose force 中間 為什麽 space problem while .com long long

Codeforces Round #466 (Div. 2)

比賽時沒想出來...賽後聽大佬說了說感覺其實很簡單嘛...

這題算是個結論題吧,我們可以發現分得段的長度要麽是c要麽是1,於是就用單調隊列維護前c個數的最小值更新即可。

為什麽要麽是c要麽是1呢?感性的理解一下,如果一段長度為c+1的,那麽將其拆成c和1的話,一定不會更差,因為如果最小值在中間的話,值是一樣的,在兩邊的話值會更優。對於c+2也是一樣的道理,在中間沒影響,在兩端的2個的話答案會更優....

其他都是同理。

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define
LL long long 3 using namespace std; 4 const int inf=1e5+10; 5 int n,c; 6 int a[inf]; 7 LL f[inf],s[inf]; 8 struct ghb{ 9 int id,val; 10 }que[inf]; 11 int l,r; 12 int main() 13 { 14 scanf("%d%d",&n,&c); 15 for(int i=1;i<=n;i++)scanf("%d",&a[i]),s[i]=s[i-1
]+a[i]; 16 l=1;r=0; 17 for(int i=1;i<=n;i++){ 18 f[i]=f[i-1]+a[i]; 19 while(l<=r&&que[l].id<=i-c)l++; 20 while(l<=r&&a[i]<que[r].val)r--; 21 que[++r]=(ghb){i,a[i]}; 22 if(i>=c){ 23 f[i]=min(f[i-c]+s[i]-s[i-c]-que[l].val,f[i]);
24 } 25 } 26 printf("%lld\n",f[n]); 27 return 0; 28 }
View Code

Codeforces Round #466 (Div. 2) ---e