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 ...
随机推荐
- vue中如何使用event对象
原文地址 一.event 对象 (一)事件的 event 对象 你说你是搞前端的,那么你肯定就知道事件,知道事件,你就肯定知道 event 对象吧?各种的库.框架多少都有针对 event 对象的处理. ...
- vue/cli 3.0配置NODE_ENV
原文地址 在项目开发中我们需要配置环境变量,开发环境,生产环境和测试环境.在cli 2.0的版本中我们是通过在config文件夹进行配置的,vue/cli 3.0相对简单,只需要在项目根目录创建.en ...
- appium+python+Windows自动化测试文档
appium+python自动化测试文档 一.认识appium 1. 什么是appium appium是开源的移动端自动化测试框架: appium可以测试原生的.混合的.以及移动端的web项目: ...
- MBProgressHUD长时间加载无法取消的解决方法
使用MBProgressHUD时,加载网路数据,或者等待webview加载完毕,长时间的等待导致体验不佳,这时候希望点击屏幕取消加载动画效果: // MBProgressHUD.h @protocol ...
- 【CodeForces - 598D】Igor In the Museum(bfs)
Igor In the Museum Descriptions 给你一个n*m的方格图表示一个博物馆的分布图.每个方格上用'*'表示墙,用'.'表示空位.每一个空格和相邻的墙之间都有一幅画.(相邻指的 ...
- 喜欢听DJ的朋友可以自己用下,别传播
// ==UserScript== // @icon http://djkk.com/favicon.ico // @name DJKK Downloader // @namespace http:/ ...
- robots.txt文件
网站通过一个符合Robots协议的robots.txt文件来告诉搜索引擎哪些页面可以爬取.Robots.txt协议全称“网络爬虫排除标准”.一般情况下,该文件以一行或多行User-agent记录开始, ...
- IDEA 2019.2破解激活教程(激活到2089年8月,亲测有效,持续更新中...)
本来笔者这边是有个正版激活码可以使用的,但是,2019.9月3号的时候,一些小伙伴反映这个注册码已经失效了,于是拿着自己的 IDEA, 赶快测试了一下,果不其然,已然是不能用了. 好在,笔者又找到了新 ...
- 通过js判断整型,浮点型,布尔型,字符串型
<!DOCTYPE html> <html > <head> <meta charset="UTF-8"> < ...
- 归并排序+归并排序求逆序对(例题P1908)
归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然 ...