序列变换
给定序列A={A1,A2,...,An}A={A1,A2,...,An}, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi<Bi+1,1≤i<NBi<Bi+1,1≤i<N)。
我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai−Bi|)(1≤i≤N)cost(A,B)=max(|Ai−Bi|)(1≤i≤N)。
请求出满足条件的最小代价。
注意,每个元素在变换前后都是整数。
我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai−Bi|)(1≤i≤N)cost(A,B)=max(|Ai−Bi|)(1≤i≤N)。
请求出满足条件的最小代价。
注意,每个元素在变换前后都是整数。
Input第一行为测试的组数T(1≤T≤10)T(1≤T≤10).
对于每一组:
第一行为序列A的长度N(1≤N≤105)N(1≤N≤105),第二行包含N个数,A1,A2,...,AnA1,A2,...,An.
序列A中的每个元素的值是正整数且不超过106106。Output对于每一个测试样例,输出两行:
第一行输出:"Case #i:"。i代表第 i 组测试数据。
第二行输出一个正整数,代表满足条件的最小代价。Sample Input
2 2 1 10 3 2 5 4
Sample Output
Case #1: 0 Case #2: 1
二分一波乱搞
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> typedef long long ll; using namespace std; const ll inf = 1e7; const int mod = 1000000007; const int mx = 1e6; //check the limits, dummy ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } #define swa(a,b) a^=b^=a^=b #define re(i,a,b) for(ll i=(a),_=(b);i<_;i++) #define rb(i,a,b) for(ll i=(b),_=(a);i>=_;i--) #define clr(a) memset(a, 0, sizeof(a)) #define lowbit(x) ((x)&(x-1)) #define mkp make_pair int N; int t; int a[mx],n,m,ans=-1,b[mx],l=0,r=inf,mid; int check(int mid, int n) { for (int i = 1; i <= n; i++) b[i] = a[i]; b[1] -= mid; for (int i = 2; i <= n; i++) { if (a[i] > b[i - 1]) { if (a[i] - mid > b[i - 1]) b[i] -= mid; else b[i] = b[i - 1] + 1; } else { if (b[i - 1] + 1 - a[i] <= mid) b[i] = b[i - 1] + 1; else return 0; } } return 1; } int main() { cin >> t; re(cas,1,t+1) { ans = -1, l = 0, r = inf; cin >> n; re(i, 1, n+1)cin >> a[i]; while (l<=r) { mid = (l + r) /2; if (check(mid, n)) { ans = mid; r = mid - 1; } else l = mid + 1; } cout << "Case #" << cas << ':' << endl; cout << ans << endl; } return 0; }