ACM_水题|hdu5248序列变换(二分+贪心)基础题

题意(中文的直接粘题意吧)
序列变换


Problem Description
给定序列A={A1,A2,...,An}, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi

我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai?Bi|)(1≤i≤N)。


请求出满足条件的最小代价。


注意,每个元素在变换前后都是整数。



Input
第一行为测试的组数T(1≤T≤10).


对于每一组:
第一行为序列A的长度N(1≤N≤105),第二行包含N个数,A1,A2,...,An.
序列A中的每个元素的值是正整数且不超过106。



Output
对于每一个测试样例,输出两行:


第一行输出:"Case #i:"。i代表第 i 组测试数据。


第二行输出一个正整数,代表满足条件的最小代价。



Sample Input
2
2
1 10
3
2 5 4



Sample Output
Case #1:
0
Case #2:
1


思路:
思路简单一下就能想到,二分当前答案,对于当前答案,从头开始贪心,能小就尽可能的小就行了。
【ACM_水题|hdu5248序列变换(二分+贪心)基础题】


#include #includeint A[100005] ,B[100005]; int maxx(int x ,int y) { return x > y ? x : y; }int jude(int k ,int n) { for(int i = 1 ; i <= n ; i ++) { if(i == 1) B[i] = A[i] - k; else { if(A[i] > B[i-1]) B[i] = maxx(B[i-1]+1 ,A[i] - k); else { if(A[i] + k > B[i-1]) B[i] = B[i-1]+1; else return 0; } }} return 1; }int main () { int t ,n ,cas = 1 ,i; scanf("%d" ,&t); while(t--) { scanf("%d" ,&n); for(i = 1 ; i <= n ; i ++) scanf("%d" ,&A[i]); int low = 0 ,up = 1000005 ,mid ,ans; while(low <= up) { mid = (low + up) >> 1; if(jude(mid ,n)) ans = mid ,up = mid - 1; else low = mid + 1; } printf("Case #%d:\n" ,cas ++); printf("%d\n" ,ans); } return 0; }




    推荐阅读