HDU3434 Sequence Adjustment

题意:给你含有n个数的序列,每次你可以选一个子序列将上面所有的数字加1或者减1,目标是把所有数字变成相同的,问最少步数,和那个相同的数字有多少种可能。

将原序列转化为差分序列,即a[2] - a[1], a[3] -a[2]……, a[n] - a[n -1]

将原序列l,到r增加1,相当于差分序列l处加1,r + 1减1,讲从l处到尾加1,相当于差分序列l处加1

减法与此类似

故将差分序列中元素正负可以相消,总的次数为正数和与负数和绝对值的最大值。

最终变换后的序列值可取a[1]到a[n]的每个数(还没想到怎么证明)

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 1000008, INF = 0x3F3F3F3F;
int a[N];
int main(){
int t;
cin>>t;
for(int cas = 1; cas <= t; cas++){
int n;
scanf("%d", &n);
LL s1 = 0, s2 = 0;
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
if(i){
if(a[i] > a[i - 1]){
s1 += a[i] - a[i - 1];
}else{
s2 += a[i - 1] - a[i];
}
}
}
printf("Case %d: %I64d %I64d\n", cas, max(s1, s2), abs((LL)a[0] - a[n - 1]) + 1ll);
} return 0;
}

  

上一篇:m3u8文件简介


下一篇:Linq处理list数据