一场个人选拔赛的题目 感觉自己还是菜的 这是那场唯一做出来的题目(我放过了n道水题。。。/捂脸)
本来没在意 后来听同学说网上解法思路 和我的不一样 然后我就把这道题我的代码贴出来
题意就是按照题目的规则计算下用最小的cost让原序列编程一个严格的单调递增序列
cost(A,B)=max(|Ai−Bi|)(1≤i≤N)
我的想法是先假设构造一个以以A【0】为首项 以1为差值的理想递增数列
然后再求出每个项与理想序列的差值 差值有正负 分别记录最大值和最小值
中间过程看如果有非严格递增的两项就更改标志变量 表示需要更改序列
然后输出(差值的最大值 - 差值的最小值 + 1) / 2 即答案 (这也包括改变首项的情况 一个从整体考虑的想法)
有点遗憾的是我不能给出证明 如果读者有谁能够给出证明的话就好了
#include<cstdio>//hdu5248 序列变换(贪心)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 5;//先假设构造一个以以A【0】为首项 以1为差值的理想递增数列
int num1[maxn], num2[maxn];//num1 原数列 num2存num1[i] 与 num1[0] + i之差 即 与理想数列对应的每个项的cost
int main(){
int a, i, j, n, t, cas, b, minx, maxx, f;//maxx记录最大的cost minx记录最小的cost f标记是否需要更改
long long ans;
scanf("%d", &t);
cas = 0;
while(t --){
cas ++;
printf("Case #%d:\n", cas);
scanf("%d", &n);
maxx = 0;
minx = 0;
for(i = 0, f = 1; i < n; i ++){
scanf("%d", &num1[i]);
if(i && num1[i] <= num1[i - 1])//需要更改
f = 0;
num2[i] = num1[0] + i - num1[i];
maxx = max(maxx, num2[i]);
minx = min(minx, num2[i]);
}
if(!f)
printf("%d\n", (maxx - minx + 1) / 2);//最小代价
else
printf("0\n");
}
return 0;
}
cost(A,B)=max(|Ai−Bi|)(1≤i≤N)cost(A,B)=max(|Ai−Bi|)(1≤i≤N)。