16.1113 模拟考试T1
2016-11-13 16:17
246 查看
笔记
【问题描述】
给定一个长度为m的序列a,下标编号为1~m。序列的每个元素都是1~N的
整数。定义序列的代价为累加(1->m-1 abs(ai+1-ai))
你现在可以选择两个数x和y,并将序列?中所有的x改成y。x可以与y相等。
请求出序列最小可能的代价。
【输入格式】
输入第一行包含两个整数n和m。第二行包含n个空格分隔的整数,代表序
列a。
【输出格式】
输出一行,包含一个整数,代表序列最小的代价。
【样例输入 1】
4 6
1 2 3 4 3 2
【样例输出 1】
3
【样例输入 2】
10 5
9 4 3 8 8
【样例输出 1】
6
【样例解释】
样例 1 中,最优策略为将 4 改成 3。样例 2 中,最优策略为将 9 改成 4。
【数据规模和约定】
对于30%的数据,n,m<=100
对于60%的数据,n,m ≤ 2000。
对于100%的数据,1 ≤ n,m ≤ 100,000。
思路:动态数组记录下与每个数字相邻的所有数字,若是要修改这这个数字的话,肯定是从与它相邻的数字中间取中位数(先sort)这样对于答案的贡献肯定最小,before记录改之前的值,sum记录所有改之前的值,sum/2是因为相邻的两个数字肯定是互相相邻的,即每一个数字都被计算了两遍,ans记录对答案贡献较大的修改值,即遍历一遍检查修改1-N中的哪个数字,可以使答案更优,before-after为将i修改为
数据:见网盘我叫雷锋~ 提取密码:gmcf
【问题描述】
给定一个长度为m的序列a,下标编号为1~m。序列的每个元素都是1~N的
整数。定义序列的代价为累加(1->m-1 abs(ai+1-ai))
你现在可以选择两个数x和y,并将序列?中所有的x改成y。x可以与y相等。
请求出序列最小可能的代价。
【输入格式】
输入第一行包含两个整数n和m。第二行包含n个空格分隔的整数,代表序
列a。
【输出格式】
输出一行,包含一个整数,代表序列最小的代价。
【样例输入 1】
4 6
1 2 3 4 3 2
【样例输出 1】
3
【样例输入 2】
10 5
9 4 3 8 8
【样例输出 1】
6
【样例解释】
样例 1 中,最优策略为将 4 改成 3。样例 2 中,最优策略为将 9 改成 4。
【数据规模和约定】
对于30%的数据,n,m<=100
对于60%的数据,n,m ≤ 2000。
对于100%的数据,1 ≤ n,m ≤ 100,000。
#include <cstdio> #include <iostream> #include <algorithm> #include <ios> #include <vector> using namespace std; typedef long long ll; const int N = (int)1e5; int n, m, a[N+1]; vector<int> b[N+1]; int main(int argc, char *argv[]) { freopen("note.in", "r", stdin); freopen("note.out", "w", stdout); ios :: sync_with_stdio(false); cin>>n>>m; for (int i=1;i<=m;++i) cin>>a[i]; for (int i=1;i<=m;++i) { if (i>1&&a[i-1]!=a[i]) b[a[i-1]].push_back(a[i]); if (i<m&&a[i+1]!=a[i]) b[a[i+1]].push_back(a[i]); } ll ans=0LL,sum=0LL; for (int i=1;i<=n;++i){ if (!b[i].size()) continue; sort(b[i].begin(),b[i].end()); int y=b[i][b[i].size()>>1]; ll before=0LL,after=0LL; for (int j=0;j<b[i].size();++j) { before+=abs(i-b[i][j]); after+=abs(y-b[i][j]); } ans=max(ans,before-after),sum+=before; } cout<<sum/2-ans<<endl; fclose(stdin); fclose(stdout); return 0; }
思路:动态数组记录下与每个数字相邻的所有数字,若是要修改这这个数字的话,肯定是从与它相邻的数字中间取中位数(先sort)这样对于答案的贡献肯定最小,before记录改之前的值,sum记录所有改之前的值,sum/2是因为相邻的两个数字肯定是互相相邻的,即每一个数字都被计算了两遍,ans记录对答案贡献较大的修改值,即遍历一遍检查修改1-N中的哪个数字,可以使答案更优,before-after为将i修改为
int y=b[i][b[i].size()>>1]前后差值,即修改i对答案的优化程度
数据:见网盘我叫雷锋~ 提取密码:gmcf
相关文章推荐
- 16.1113 模拟考试T2
- 16.1112 模拟考试 T1
- 16.1113 模拟考试T3
- 16.1113 模拟考试T2
- 16.1114 模拟考试T1
- 16.1112 模拟考试 T1
- 16.1113 模拟考试T3
- 16.1114 模拟考试T1
- 关于模拟考试网站
- 计算机等级考试二级C++上机模拟试题11套汇总及答案解释(三)
- 求中间数:CCF计算机职业资格认证考试模拟试题,编号:201612-1
- 【NOIP普及组】2016模拟考试(10.29)——海港的船只
- 模拟考试1 BestCoder Round #2 TIANKENG’s restaurant
- 驾照模拟考试所得。
- 2017.9.9模拟考试
- [模拟][NOIP2011] (提高组)D1 T1 铺地毯
- jsp+servlet模拟从题库中随机选出3道题目考试
- 2004年网络工程师考试模拟试题二
- 特长生模拟——12年东莞市特长生考试
- PMP在线考试系统—全真模拟试题(完全免费)