Codeforces Round #466 (Div. 2) ---e
阿新 • • 發佈:2018-02-25
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 #defineView CodeLL 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 }
Codeforces Round #466 (Div. 2) ---e