POJ1722 算法竞赛进阶指南 SUBSTRACT减操作
题目描述
给定一个整数数组\(a_1,a_2,…,a_n\)。
定义数组第 i 位上的减操作:把\(a_i\)和\(a_{i+1}\)换成\(a_i - a_{i+1}\)。
用con(a,i)表示减操作,可以表示为:
\]
长度为 n 的数组,经过 n-1 次减操作后,就可以得到一个整数t。
例如数组[12,10,4,3,5]经过如下操作可得到整数4:
\\
con([12,6,3,5] ,3) = [12,6,-2]
\\
con([12,6,-2] ,2) = [12,8]
\\
con([12,8] ,1) = [4]
\]
现在给定数组以及目标整数,求完整操作过程。
输入格式
第1行包含两个整数n和t。
第2..n+1行:第i行包含数组中的第 i 个整数\(a_i\)。
输出格式
输出共n-1行,每行包含一个整数,第 i 行的整数表示第 i 次减操作的操作位置。
数据范围
-10000 \le t \le 10000 \\
1 \le a_i \le 100 \\
\]
输入样例:
5 4
12
10
4
3
5
输出样例:
2
3
2
1
解题报告
题意理解
就是说,有一种操作,名为减操作,可以将合并相邻的两个数,比如说原来的数字是.
\]
也就是,
a[i]=a[i]-a[i-1] \\
然后删除a[i+1]
\]
思路解析
性质分析
我们发现,每一次减操作都会使得序列长度减少一个.
\]
所以说,我们发现其实对于序列的最终结果\(t\),可以变成这种形式.
\]
举个例子表示一下
a[1] \quad a[2]-a[3] \quad a[4] \quad [5] \qquad 此时cut(2) \\
a[1] \quad a[2]-a[3] \quad a[4]-a[5] \qquad 此时cut(3) \\
a[1] \quad a[2]-a[3]-(a[4]-a[5]) \qquad 此时cut(2) \\
a[1]-(a[2]-a[3]-(a[4]-a[5])) \qquad 最后cut(1) \\
a[1]-a[2]+a[3]+a[4]-a[5] \qquad 处理后的答案序列
\]
我们发现
\]
对于
\]
因为我们发现,\(1\)的前面没有数,可以去进行减操作.
最后一次执行的必然是\(cut(1)\)操作
\(a[1]\)表示,我真的想要减操作,但是我就是没有数可以和我一起减操作.
然后我们再来康康为什么一定是
\]
其实道理和之前一样,
最后一次执行的必然是\(cut(1)\)操作.
\(a[2]\)表示,我真的是被迫的,\(cut(1)\)使得\(a[1]-a[2]\).
状态设置
这样我们将题目转换成了
一个数列,对于数组中的数,将一些正整数变为负数,使整个数组的和为t,最后输出将哪些数变为负数.
我们发现这道题目的数据范围
-10000 \le t \le 10000 \\
\]
数据范围真的好小啊,开一个\(n*t\)的数据范围丝毫没有问题.
所以说我们不妨这么设置一个状态数组.
f[i][cnt]=1 \quad 表示第i个数前面是+号 \\
f[i][cnt]=-1 \quad 表示第i个数前面是-号 \\
\]
不过我们要注意一下,C++负数下标有可能性挂掉了,所以我们不得不让所有下标加上一个固定的大数字,保证最后的下标是一个正数.
此时最大的问题就是,如何反推出我们的cut操作?
反推路径
- 为什么有些数可以是正数?也就是前面是+号?
这是一个非常重要的问题,我们发现.
\]
假如说我们第\(i\)位不进行\(cut\)操作,那么它前面一定不是\(+\)号.
一个数,前面不是加号,就是减号.
cut(i-1) \qquad a[i-1]-a[i] \\
\]
只有当\(i-1\)位进行\(cut\)操作的时候,这个第\(i\)位才可以是减号.
这就让我们证明了.
\]
所以找到每一个\(+\)号的位置,然后输出当前位置.
不过你要注意一下,输出应该是.
tot表示为当前有几个cut操作了 \\
\]
代码解析
#include<bits/stdc++.h>
using namespace std;
#define init() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);//读入优化
const int maxn=105,maxt=20086,hh=10000;//hh是我们的下标转移常数
int n,t,f[maxn][maxt],a[maxn],ans[maxn];
void dp()
{
f[1][a[1]+hh] = 1;//a[1]必然是正数
f[2][a[1]-a[2]+hh]=-1;//a[2]必然是
for(int i=3; i<=n; i++)
for(int j=-10000+hh; j<=10000+hh; j++)
{
if(f[i-1][j])//可以转移
{
f[i][a[i]+j]=1;//+号
f[i][j-a[i]]=-1;//-号
}
}
}
void out()
{
int s=hh+t;
for(int i=n; i>=2; i--)//回溯走路径,确定+,-号
{
ans[i]=f[i][s];
if(ans[i]==1)
s-=a[i];
else if(ans[i]==-1)
s+=a[i];
}
int cnt=0;
for(int i=2; i<=n; i++)
if(ans[i]==1)//是时候减操作了.
{
cout<<i-cnt-1<<endl;
cnt++;
}
for(int i=2; i<=n; i++)
if(ans[i]==-1)//寻找
cout<<1<<endl;
}
int main()
{
init();
cin>>n>>t;
for(int i=1; i<=n; i++)
cin>>a[i];
dp();
out();
return 0;
}
POJ1722 算法竞赛进阶指南 SUBSTRACT减操作的更多相关文章
- 算法竞赛进阶指南0x51 线性DP
AcWing271. 杨老师的照相排列 思路 这是一个计数的题目,如果乱考虑,肯定会毫无头绪,所以我们从1号到最后一个依次进行安排. 经过反复实验,发现两个规律 每一行的同学必须是从左向右依次连续放置 ...
- 算法竞赛进阶指南0x35高斯消元与线性空间
高斯消元 目录 高斯消元 ACWing207. 球形空间产生器(点击访问) 求解思路 代码 ACWing208. 开关问题(点击访问) 思路 代码 总结 欣赏 线性空间 定义 ACWing209. 装 ...
- 算法竞赛进阶指南0x34矩阵乘法
文章目录 矩阵的相关性质再回顾 矩阵加速大法: ACWing205. 斐波那契 代码 ACWing206. 石头游戏 解题思路: 感受: 代码 矩阵的相关性质再回顾 对于一个矩阵 满足结合律 满足乘法 ...
- 《算法竞赛进阶指南》0x10 基本数据结构 Hash
Hash的基本知识 字符串hash算法将字符串看成p进制数字,再将结果mod q例如:abcabcdefg 将字母转换位数字(1231234567)=(1*p9+2*p8+3*p7+1*p6+2*p5 ...
- 《算法竞赛进阶指南》1.4Hash
137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南
题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...
- POJ1639 算法竞赛进阶指南 野餐规划
题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...
- 算法竞赛进阶指南 0x00 基本算法
放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...
- 算法竞赛进阶指南--快速幂,求a^b mod p
// 快速幂,求a^b mod p int power(int a, int b, int p) { int ans = 1; for (; b; b >>= 1) { if (b &am ...
随机推荐
- Warning:detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd".
执行kubeadm init集群初始化时遇到: [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker ...
- python基础学习19,01
听说python入门很容易,所以想试试对我这个零基础会不会很友好呢.做随笔也顺便督促自己不要轻易放弃学习. #登录接口 print("请输入用户名密码") _username = ...
- 并查集 --cogs456 岛国
题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=pNyNQiqge 思路: 基础是并查集,将两个相邻的岛算作一个集合,每次若合并成功,则N ...
- 生产环境Crontab专业实例
1)书写Crontab定时任务多个基本要领 1.规范定时任务两例 例1:每分钟打印一次自己名字的全拼到 “/server/log/自己命名的文件” 中
- Redis(1.9)Redis主从复制
[1]实验环境 CentOS7.5 + Redis4.0.11 架构:原生1主2从,做实验机器有限,从库双实例 主库:192.168.135.170 从库1:192.168.135.171~6379 ...
- VIM 介绍
gedit a.txt 是一个图形界面的文本编辑器. 需要安装图形界面才会有. nano a.txt 也是一样的 vi 是一种文本界面的编辑器. vim 是 vimsual interfa ...
- day05-06
day05 上传下载 下载工具软件: lrzsz 安装方法: yum install lrzsz -y 下载命令就是sz 上传命令就是rz 下载到widow实列 sz 文件名 上传到linux 执行r ...
- 并不对劲的CF480E:Parking Lot
题目大意 有一个\(n\times m\)的网格,每个位置是黑色或者白色.\(k\)个操作,每个操作是将一个白格子染黑,操作后输出当前最大的白色正方形的边长.\(n,m,k\leq 2\times 1 ...
- Codeforces 1240B. Sequence Sorting
传送门 分析题目发现如果把某个数 $x$ 往左移,那么之后所有小于 $x$ 的数也都要往左移 如果把 $x$ 往右移,那么之后所有大于 $x$ 的数也都要往右移 考虑我们首先一定有一个操作 $n$ 次 ...
- Java String类和StringBuffer类
1.String类 用于字符串操作,本质是字符数组char[ ]. String对象的值是不可变的,即当你修改一个String对象的类容,JVM不会改变原来的对象,而是生成一个新String对象. 2 ...