码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5248 序列变换(二分枚举)

时间:2015-09-11 22:02:22      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

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

我们定义从序列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

 

 

 

Source
 

 二分枚举最小的代价。从后往前枚举判断序列是否为单调递减

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<stdlib.h>
 6 #include<cmath>
 7 #include<algorithm>
 8 using namespace std;
 9 #define N 100006
10 #define inf 1<<30
11 int n;
12 int a[N];
13 bool solve(int mid){
14     int tmp=a[n]+mid;
15     for(int i=n-1;i>=1;i--){
16         if(abs(tmp-1-a[i])<=mid){
17             tmp=tmp-1;
18         }
19         else if(tmp-1>=a[i]){
20             tmp=a[i]+mid;
21         }
22         else{
23              return false;    
24         }
25     }
26     return true;
27 }
28 int main()
29 {
30     int ac=0;
31     int t;
32     scanf("%d",&t);
33     while(t--){
34         scanf("%d",&n);
35         for(int i=1;i<=n;i++){
36             scanf("%d",&a[i]);
37         }
38         int low=0;
39         int high=inf;
40         while(low<high){
41             int mid=(low+high)>>1;
42             if(solve(mid)){
43                 high=mid;
44             }
45             else{
46                 low=mid+1;
47             }
48         }
49         printf("Case #%d:\n",++ac);
50         printf("%d\n",low);
51         
52     }
53     return 0;
54 }
View Code

 

hdu 5248 序列变换(二分枚举)

标签:

原文地址:http://www.cnblogs.com/UniqueColor/p/4802088.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!