标签:不能 round 解析 while cstring main typedef i+1 scan
地址:http://codeforces.com/contest/1453/problem/B
题意:
给定你一个长度为n的序列,你有两种操作,给这个序列的后缀加一或者减一,序列的后缀定义和字符串的后缀定义相同,还有你开始在所有的操作开始的时候,选择把一个数变成任意的数,这个操作不计入总的操作次数,然后问你最少需要操作几次,才能将这个序列都变成相等的数。
解析:
先考虑不提前改数的情况,a2~an全变成a1,前提是a3~an全变成a2,那么有:
fabs(ai-ai+1) 1<=i<=n-1
改数,怎么改是关键。肯定不能凭空乱改,可以大胆猜测是将某个数改成数组里已经存在的一个数
考虑有三个数:
一:1 5 8 原花费为7。1变成5可以将操作降为4,即a1变为a2
二:8 5 1,原花费为7。1变成5可以将操作降为4,即an变为an-1
三:5 2 10,原花费为11 ,只有2变为10,操作最小降为5,即ai+1变为ai+2。
四:5 10 2 ,原花费为11,只有10变为2,操作最小降为3,即ai+1变为ai+2。
三四可以概括为一种,减少的操作数为:abs(ai+1-ai)+abs(ai+2-ai+1)-abs(ai+2-ai)
有代码:
#include<iostream> #include<cstring> #include<map> #include<algorithm> #include<stack> #include<queue> #include<cstdio> #include<cmath> #include<string.h> using namespace std; typedef long long ll; const int maxn=2e5+10; const int inf=99999999; int a[maxn]; ll num[maxn]; int main() { int t; scanf("%d",&t); while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; ll sum=0; for(int i=1;i<=n-1;i++) sum+=fabs(a[i]-a[i+1]); ll md=-inf; for(int i=1;i<=n-2;i++) { ll now=fabs(a[i+1]-a[i])+fabs(a[i+2]-a[i+1])-fabs(a[i+2]-a[i]); md=max(md,now); } ll s1=0,s2=0,s3=0; for(int i=1;i<=n-2;i++) { s1+=fabs(a[i]-a[i+1]); } for(int i=2;i<=n-1;i++) s2+=fabs(a[i]-a[i+1]); cout<<min(min(s1,s2),sum-md)<<endl; } }
Codeforces Round #688 (Div. 2)B. Suffix Operations(思维题)
标签:不能 round 解析 while cstring main typedef i+1 scan
原文地址:https://www.cnblogs.com/liyexin/p/14146215.html