一道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 ...
随机推荐
- 08、元组tuple
元组(tuple) 是一个有序且不可变的容器,在里面可以存放多个不同类型的元素 元组是在最后多一个逗号,用于表示它是一个元组 tuple = (11,22,'阿斯顿','媚媚',) #后面多加一个逗号 ...
- RPC 框架设计
RPC 框架设计 初识 RPC 服务化有什么好处? 防止代码拷贝 防止底层复杂性的扩散 防止公共库的耦合 保证 SQL 的质量,能够解除数据库的耦合 什么是 RPC RPC:Remote Proced ...
- 【RocketMQ源码分析】深入消息存储(2)
前文回顾 CommitLog篇 --[RocketMQ源码分析]深入消息存储(1) MappedFile篇 --[RocketMQ源码分析]深入消息存储(3) 前文说完了一条消息如何被持久化到本地磁盘 ...
- 在ASP.NET Core中使用ViewComponent
前言 在之前的开发过程中,我们对于应用或者说使用一些小的组件,通常使用分布页(partial view),再往前在Web Form中我们会进行应用WEB Control,好吧提及一个关键性代码TagP ...
- [.net] 关于Exception的几点思考和在项目中的使用(一)
本文链接 https://www.cnblogs.com/hubaijia/p/about-exceptions-1.html 关于exception的基本语法和作用,这里不再赘述,下面记录一下我在项 ...
- centos 7升级gcc到10.2.0
安装gcc 由于 Linux 操作系统的自由.开源,在其基础上衍生出了很多不同的 Linux 操作系统,如 CentOS.Ubuntu.Debian 等.这些 Linux 发行版中,大多数都默认装有 ...
- 带你全面认识CMMI V2.0(四)——管理 赋能
风险和机会管理(PSK)包括:识别威胁和机会:评估其发生和影响的可能性:减轻潜在威胁:利用潜在机会目的:识别,记录,分析和管理潜在的风险或机会.价值:减轻不利影响或利用积极影响来增加实现目标的可能性. ...
- MySQL数据库高级二:索引优化
索引优化非常的重要 1.预热 java开发 DBA培训很少,需要经验磨练 索引优化的效果非常好 左外连接 MySQL没有全连接 7种join一定要会写 具体见武林的例子 union的字段顺序要相同 6 ...
- create-react-app 核心思路分析
原文链接:http://axuebin.com/articles/fe-solution/cli/cra.html,转载请联系 Create React App is an officially su ...
- (三)LDAP 新增用户
LDAP 新增用户 图一: 图二:LAM 配置 图三: 图四:全局配置 输入LAM控制台的密码,默认是LAM 图五: