jzoj4788-[NOIP2016提高A组模拟9.17]序列【差分,贪心】
正題
題目大意
一個序列AAA可以每次選擇一段區(qū)間(Ai+1)%4(i∈[l..r])(A_{i}+1)\%4(i\in [l..r])(Ai?+1)%4(i∈[l..r])。求最少次數(shù)使其變成BBB序列。
解題思路
先計算出每個數(shù)字最少加多少可以變成目標數(shù)字記錄入aaa數(shù)組。
然后若不考慮一個數(shù)要取模多次的話答案就是
∑i=1nmax?{ai?ai?1,0}(a0=0)\sum_{i=1}^n \max\{a_i-a_{i-1},0\}(a_{0}=0)i=1∑n?max{ai??ai?1?,0}(a0?=0)
但是這道題變成了每個柱子的高度是4ki+ai(k∈N)4k_{i}+a_{i}(k\in \mathbb{N})4ki?+ai?(k∈N)
那么我們考慮若一段區(qū)間[l..r][l..r][l..r]的kkk要加1會更優(yōu)那么有
al?al?1+4<ar+1?ara_{l}-a_{l-1}+4<a_{r+1}-a_{r}al??al?1?+4<ar+1??ar?
那么答案就可以減去(ar+1?ar)?(al?al?1+4)(a_{r+1}-a_{r})-(a_{l}-a_{l-1}+4)(ar+1??ar?)?(al??al?1?+4)
那么我們枚舉rrr,開個桶來計算lll
codecodecode
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=101000; int T,n,a[N],ans=2147483647,t[5]; int main() {scanf("%d",&T);while(T--){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);memset(t,0,sizeof(t));ans=0;for(int i=1;i<=n;i++){int val;scanf("%d",&val);a[i]=(val-a[i]+4)%4;ans+=max(a[i]-a[i-1],0);}for(int i=2;i<=n;i++){int c=a[i]-a[i-1];if(c>0){if(t[1]&&c>1) t[1]--,t[c]++,ans-=c-1;else if(t[2]&&c>2) t[2]--,t[c]++,ans-=c-2; }else t[c+4]++;}printf("%d\n",ans);} } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的jzoj4788-[NOIP2016提高A组模拟9.17]序列【差分,贪心】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jzoj4786-[NOIP2016提高
- 下一篇: 国美回应“总部人去楼空”称不实消息,目前