序列变换(hdu5248)

序列变换

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 774    Accepted Submission(s): 359

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

我们定义从序列A到序列B变换的代价为cost(A,B)=max(|AiBi|)(1iN)

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

注意,每个元素在变换前后都是整数。
 
Input
第一行为测试的组数T(1T10).

对于每一组:
第一行为序列A的长度N(1N105),第二行包含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
分析:二分枚举最大改变量,对于改变量mid,b[1]-=mid,然后比较接下来的b[i]如果比b[i-1]大,则看b[i]-mid是否大于b[i-1],是的话b[i]-=mid,否则b[i]=b[i-1]+1;
如果b[i]小于等于b[i-1],看b[i]=b[i-1]+1是否与a[i]的差值小于等于mid,是的话b[i]=b[i-1]+1;否则的话b[i]没法改变....mid不成立
程序:
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"algorithm"
#include"queue"
#include"math.h"
#include"iostream"
#include"vector"
#define M 100009
#define inf 0x3f3f3f3f
#define eps 1e-9
#define PI acos(-1.0)
#include"map"
#include"vector"
#include"set"
#include"string"
using namespace std;
int a[M],b[M];
int Fabs(int a)
{
    if(a<0)
        a=-a;
    return a;
}
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()
{
    int T,kk=1;
    cin>>T;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int l=0;
        int r=1000001;
        int mid;
        int ans=-1;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(check(mid,n))
            {
                ans=mid;
                r=mid-1;
            }
            else
               l=mid+1;
        }
        printf("Case #%d:\n",kk++);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 
posted @ 2015-08-05 15:03  一样菜  阅读(649)  评论(0编辑  收藏  举报