1706C - Qpwoeirut And The City
作者:互联网
/* * |~~~~~~~| * | | * | | * | | * | | * | | * |~.\\\_\~~~~~~~~~~~~~~xx~~~ ~~~~~~~~~~~~~~~~~~~~~/_//;~| * | \ o \_ ,XXXXX), _..-~ o / | * | ~~\ ~-. XXXXX`)))), _.--~~ .-~~~ | * ~~~~~~~`\ ~\~~~XXX' _/ ';)) |~~~~~~..-~ _.-~ ~~~~~~~ * `\ ~~--`_\~\, ;;;\)__.---.~~~ _.-~ * ~-. `:;;/;; \ _..-~~ * ~-._ `'' /-~-~ * `\ / / * | , | | * | ' / | * \/; | * ;; | * `; . | * |~~~-----.....| * | \ \ * | /\~~--...__ | * (| `\ __-\| * || \_ /~ | * |) \~-' | * | | \ ' * | | \ : * \ | | | * | ) ( ) * \ /; /\ | * | |/ | * | | | * \ .' || * | | | | * ( | | | * | \ \ | * || o `.)| * |`\\) | * | | * | | */ #include<iostream> #include<queue> #include<vector> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<unordered_map> #include<unordered_set> #include<set> #include<map> //#pragma GCC optimize(3) using namespace std; #define rep(i,x,y) for(int i=x;i<y;i++) #define scan(x) scanf("%lld",&x) // #define int long long #define lowbit(x) x&(-x) //二进制最低位所代表的数 #define PI 3.1415926535 inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int _read(){ char ch=nc();int sum=0; while(!(ch>='0'&&ch<='9'))ch=nc(); while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc(); return sum; } typedef pair<int,int> PII; typedef long long ll; int gcd(int a,int b){ return b>0 ? gcd(b,a%b):a; } int exgcd(int a,int b,int &x,int &y) { if(!b) { x = 1,y = 0; return a; } int d = exgcd(b,a%b,y,x); y-=a/b*x; return d; } const int N = 1e5+10; const int mod = 1e9+7; const int INF = 0x3f3f3f3f; void init() { cin.tie(0),cout.tie(0); ios::sync_with_stdio(false); } int a[N]; int get(int i) { return max(0,max(a[i-1],a[i+1])-a[i]+1); } void solve() { int n; cin>>n; ll tot = 0,ans; for(int i=1;i<=n;i++)cin>>a[i]; if(n%2) { for(int i=2;i<n;i+=2) { tot += get(i); } cout<<tot<<endl; } else { for(int i=2;i<n;i+=2) { tot += get(i); } ans = tot; for(int i=n-1;i>=2;i-=2) { tot -= get(i-1); tot += get(i); ans = min(ans,tot); } // for(int i=2;i<n;i+=2) // { // tot -= get(i); // tot += get(i+1); // ans=min(ans,tot); // } cout<<ans<<endl; } } signed main() { init(); int t; cin>>t; while(t--)solve(); }View Code
思路:
找峰,并尝试补峰,找出补得最少,但数量最多的做法,并输出补的数量(两边不作峰)。
峰对奇偶数敏感,因为峰是三个数字中出一个。
所以对于奇数,没有特殊的排列:
1 0 1
1 0 1 0 1
0 1 0 1 0
所以直接判断偶数下标的元素是否要补数即可max(0,max(a[i-1],a[i+1])-a[i]+1)
对于偶数,有几种排列,但是遵循一个原则,元素是相隔的:
0 1 0 1 0 1 0 0
0 1 0 1 0 0 1 0
0 1 0 0 1 0 1 0
0 0 1 0 1 0 1 0
有一个非常巧妙的做法,就是从后往前遍历,减去原本偶数位所加上的补数,然后再减去奇数位的补数,每一次加减判断最小方案,最后输出。
tips:补数为max(0,max(a[i-1],a[i+1])-a[i]+1)
标签:1706C,City,return,int,max,tot,补数,include,Qpwoeirut 来源: https://www.cnblogs.com/yeonnyuui/p/16626580.html