一道codeforces题目引发的差分学习
题目:B. Suffix Operations
题意:给定一个长为n的数组a,你可以进行两种操作:1).后缀+1; 2)后缀-1; 问需要最少多少步操作你才能使得数组中元素全部相等,并且首先你可以改变其中任何一个元素成为任何一个数,并且不被计入步数
思路:
首先来看一下数组中大致分为这三种情况:举例
3 5 7 (上升式)这样中间的5变成3-7之间的任何一个数都能最终变成3
7 5 3 (下降式)与上述相同
7 3 5 (断崖式)最终要让他变成7,会产生浮动变化
通过上面的例子,就想到会用到差分数组(d[n]),总共的浮动次数是不变的,只需要统计如果一个数变化的时候影响最大的次数是多少,因为最终肯定会是出现阶段性的后面的数要变成它前面的数,所以要分情况讨论d[i]变化引起的d[i+1]的变化,具体看代码
代码:
1 #include<iostream>
2 #include<algorithm>
3 #include<cstdio>
4 #include<cmath>
5 #include<cstring>
6 #include<map>
7 #include<queue>
8 using namespace std;
9 const int maxx=2e5+1;//14.12
10 //找差分
11 long long int a[maxx]={0};
12 long long int d[maxx]={0};
13 int main(){
14 int n;
15 scanf("%d",&n);
16 while(n--){
17 int m;
18 scanf("%d",&m);
19
20 long long int sum=0;
21 for(int i=1;i<=m;i++){
22 scanf("%lld",&a[i]);
23 d[i]=a[i]-a[i-1];//差分数组
24 if(i>1){
25
26 sum+=abs(d[i]);
27 }
28 }
29
30 long long int maxn=0;
31 for(int i=1;i<=m;i++){
32 long long int x=abs(d[i]),y=abs(d[i+1]);
33 if(i==1){
34 maxn=max(maxn,abs(d[2]));
35 }else if(i==m){
36 maxn=max(maxn,abs(d[m]));
37 }else{
38 long long int y1;
39 if(d[i]>0){
40 y1=d[i+1]+x;
41 }else{
42 y1=d[i+1]-x;
43 }
44 maxn=max(maxn,x+y-abs(y1));
45 }
46 }
47 sum-=maxn;
48 printf("%lld\n",sum);
49
50
51 }
52 }
差分数组/前缀和的应用:
主要就是对数组中的数字进行操作,通过小区间波动改变一整个数组
1.HDU-1556 Color the Ball http://acm.hdu.edu.cn/showproblem.php?pid=1556
思路:一开始以为直接用a[maxx]数组进行遍历循环就行,结果TLE掉了,时间复杂度是O(n2),结果看了看并没有这么简单,应该是用两个数组,一个存储实际值(显然初始值都是0)c[n],一个存储浮动变化d[n]
d:0 1 0 0 -1
c:0 1 1 1 0
这样看来也有一些逆向前缀和的想法,存储的时候先存储d[i],然后按照前缀和的想法进行输出,这样时间复杂度就是O(n)
代码:
1 #include<iostream>
2 #include<algorithm>
3 #include<cstdio>
4 #include<cmath>
5 #include<cstring>
6 #include<map>
7 #include<queue>
8 using namespace std;
9 const int maxx=2e5+1;//14.12
10 int main(){
11 int n;
12 while(~scanf("%d",&n)){
13 int a[maxx]={0};
14 if(n==0){
15 break;
16 }
17 int c[maxx]={0};
18 for(int i=1;i<=n;i++){
19 int t,b;
20 scanf("%d %d",&t,&b);
21 c[t]++;
22 c[b+1]--;
23 }
24 int sum=0;
25 for(int i=1;i<=n;i++){
26 sum+=c[i];
27 printf("%d",sum);
28 if(i<n){
29 printf(" ");
30 }
31 }
32 printf("\n");
33 }
34 }
2.POJ -3263 Tallest Cow http://poj.org/problem?id=3263
思路:一开始想着用数组的加加减减,还是所有的从0开始,看他们的相对大小就好了,结果发现做的时候两边端点都加加,中间的都减减,这样出来的结果就是错的,后来发现差分数组想错了,并不是这样,而且这样也会TLE掉,这个题目中问的是最高多少,而且同时加减这样端点和中间就会差2而不是1,所以让所有的牛最初始的高度是h,然后再建立一个数组b[n]存储差分值,x,y为区间端点,b[x+1]--,b[y]++,而且这个题还需要区间判重一下,见代码
代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #include<string>
6 #include<cmath>
7 #define ll long long
8 #define mem(a,b) memset(a,b,sizeof(a))
9 using namespace std;
10 const int inf=0x3f3f3f3f;
11 const int mm=1e4+10;
12 int a[mm],b[mm];
13 int vis[mm][mm];
14 int main(){
15 int n,pos,h,r;
16 scanf("%d%d%d%d",&n,&pos,&h,&r);
17 for(int i=0;i<=h+1;i++)
18 a[i]=0;
19 int x,y;
20 for(int i=1;i<=r;i++){
21 scanf("%d%d",&x,&y);
22 if(x>y) swap(x,y);//
23 if(vis[x][y])//判重
24 continue;
25 vis[x][y]=1;
26 b[x+1]--;//后面的减少
27 b[y]++;//前面的增加
28 }
29 for(int i=1;i<=n;i++){
30 a[i]=a[i-1]+b[i];
31 printf("%d ",a[i]);
32 }
33 return 0;
34 }
TLE掉的代码:
1 #include<iostream>
2 #include<algorithm>
3 #include<cstdio>
4 #include<cmath>
5 #include<cstdio>
6 using namespace std;
7 const int maxx=1e5+10;
8 int main(){
9 int n,ii,h,r;
10 cin>>n>>ii>>h>>r;
11 int a[maxx]={0};
12 for(int i=1;i<=n;i++){
13 a[i]=h;
14 }
15 for(int i=0;i<r;i++){
16 int num1,num2;
17 scanf("%d %d",&num1,&num2);
18 if(num1>num2){
19 swap(num1,num2);
20 }
21 for(int j=num1+1;j<num2;j++){
22 a[j]--;
23 }
24 }
25 for(int i=1;i<=n;i++){
26 printf("%d ",a[i]);
27 }
28 }
一道codeforces题目引发的差分学习的更多相关文章
- 一道算法题目, 二行代码, Binary Tree
June 8, 2015 我最喜欢的一道算法题目, 二行代码. 编程序需要很强的逻辑思维, 多问几个为什么, 可不可以简化.想一想, 二行代码, 五分钟就可以搞定; 2015年网上大家热议的 Home ...
- 增强学习(五)----- 时间差分学习(Q learning, Sarsa learning)
接下来我们回顾一下动态规划算法(DP)和蒙特卡罗方法(MC)的特点,对于动态规划算法有如下特性: 需要环境模型,即状态转移概率\(P_{sa}\) 状态值函数的估计是自举的(bootstrapping ...
- 强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning)
强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning) 学习笔记: Reinforcement Learning: An Introductio ...
- 之前同事问到的一道python题目
Python面试题 之前同事问了一道Python题目如下,暂时归类为面试题 题目:把类似'123.456'的字符串转换成浮点型数据 方法一: >>> print '{:.3f}'.f ...
- Binary Search Tree 以及一道 LeetCode 题目
一道LeetCode题目 今天刷一道LeetCode的题目,要求是这样的: Given a binary search tree and the lowest and highest boundari ...
- 一道面试题引发的对 Java 内存模型的一点疑问
一道面试题引发的对Java内存模型的一点疑问 问题描述 如上图所示程序,按道理,子线程会通过 num++ 操作破坏 while 循环的条件,从而终止循环,执行最后的输出操作.但在我的多次运行中,偶尔会 ...
- js 一道题目引发的正则的学习
正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...
- 一道原生js题目引发的思考(鼠标停留区块计时)
我瞎逛个啥论坛,发现了一个题目,于是本着练手的心态就开始写起来了,于是各种问题接踵而至,收获不小. 题目是这样的: Demo: mouseenter与mouseover区别demo 跨浏览器的区块计数 ...
- 一道面试题引发的思考(C#值类型和引用类型)
某年某月,笔者去面试招行的一个外包项目,辗转来到面试地点以后,面试官给了我一份试卷,试卷只有两道题目,其中一道是这样的: 阅读以下程序 class Program { struct Point { p ...
随机推荐
- Ubuntu-搭建Clang Static Analyzer环境
其实也就是一个开源的漏洞扫描器 专门扫描C/C++ 0BJECT-C++这种,实不相瞒我搭建了5天这个环境,最后我发现了一种超级方便的办法 前面怎么走的坑还是不分享了吧,由于没有看到前面很多人的办法或 ...
- 灵魂拷问!浏览器输入「xxxxhub」的背后.....
Hey guys 各位读者姥爷们大家好,这里是程序员 cxuan 计算机网络连载系列的第 13 篇文章. 到现在为止,我们算是把应用层.运输层.网络层和数据链路层都介绍完了,那么现在是时候把这些内容都 ...
- 人多力量大vs.两个披萨原则,聊聊持续交付中的流水线模式
人多力量大vs.两个披萨原则,聊聊持续交付中的流水线模式 在前面5期文章中,我们分别详细介绍了持续交付体系基础层面的建设,主要是多环境和配置管理,这些是持续交付自动化体系的基础,是跟我们实际的业务场景 ...
- vue-cli2 生成的项目打包优化(持续学习中)
1.昨天看到自己的项目每次打包后都是30M左右,就觉得这个打包后的dist文件太大了,能不能小点呢, 然后就看网上的资料,提供了好多优化的办法,但是我只用了一个,后期再不断的优化吧. 打开工程项目文件 ...
- springcloud面试题【第一期】
全文目录 1:谈一谈你对微服务的理解? 2:微服务之间是如何独立进行通讯的? 3:springcloud和dubbo有哪些区别? 4:springboot和spring cloud得区别? 5:Eur ...
- 安卓安装kali linux之Termux
解决安装kali无模组问题 https://blog.csdn.net/weixin_44690490/article/details/108599693?utm_source=app 步骤 1.获取 ...
- Java高级【Junit、反射、注解】
1.Junit单元测试 * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. * Junit使用 ...
- Java实现基于朴素贝叶斯的情感词分析
朴素贝叶斯(Naive Bayesian)是一种基于贝叶斯定理和特征条件独立假设的分类方法,它是基于概率论的一种有监督学习方法,被广泛应用于自然语言处理,并在机器学习领域中占据了非常重要的地位.在之前 ...
- 深入剖析共识性算法 Raft
一. Raft简介 1.1 Raft简介 Raft 是一种为了管理日志复制的分布式一致性算法.Raft 出现之前,Paxos 一直是分布式一致性算法的标准.Paxos 难以理解,更难以实现.Raft ...
- qsort 快排函数(C语言)
qsort 快排函数(C语言) 函数原型 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, ...