POJ 1722 SUBTRACT
给定一个数组a[1,2,..,n] 。定义数组第i位上的减操作:把ai和ai+1换成ai - ai+1。输入一个n位数组以及目标整数t,求一个n-1次操作序列,使得最后剩下的数等于t
最后输出依此操作的i
输入:第一行一个N,一个T,接下来N行,每行一个正整数ai
输出:依次输出被操作的位置i
首先对题目进行分析后,似乎没有什么好的思路。
从结果入手。
对于最后的得到的整数,肯定是将原数列中一些数前加上了符号,然后将数列加在一起的操作。
这样我们就避免了麻烦的数组操作。‘
这样我们将题目转换成了:
一个数列[a1, a2, ....aN],对于数组中的数,将部分正整数变为负数,使整个数组的和为t,最后输出将哪些数变为负数
其中,从原题中我们可以知道:由于第1个数前没有数,所以第1个数不可能加负数,这样我们想,假设最后剩下两个数a1, a2,由原题目我们知道,要想把这两个数化为一个整数,第二个数必须为负数。
因此,在最初,第一个数必须为正,第二个数必须为负数。
然后整理能够描述状态空间的信息:
1.一个正整数i,表示进行到了第i个数
2.标记-1或1,表示第i个数取负还是取正
3.一个整数,表示进行到第i个数时,前i个数的和
接着我们要确定的是第i个数取正还是取负,然后我们还需要前i-1个数的和,但是我们能够注意到的是,前i-1个数的和是不确定的,对于i前的除了1,2位置的数,每一个数都有取正和取负两个操作,由于i可能很大
因此前i-1个数的和的结果也很多,所以对于i-1个数的和是不确定的,而对于第i个数取正还是取负,一共只有两个情况。
这样我们只能将前i-1个数的和作为变量,加一个维度,用来描述状态空间。
设f[i, j] = k表示到第i个数,前i个数的和为j时,第i个数的标记为k
这样问题的重点就在于如何记录路径了
对于我们的思路肯定是倒推回去
我们试着从f[][t]推回去
但是对于第一维,我们是并不确定的,
我们只能试着将i从2到n一个一个搜,但是注意的是i不能从1开始,最后我们处理1时再说原因
我们从我们的策略分析:我们可以发现,我们首先需要输出的显然是一路倒推后标记为1的i值,但是我们有一点就是我们每操作一个i,i之后的数的下标会全部减1。
因此首先我们首先要从答案一路逆推回去,同时开一个新数组,在第i个位置标记这个数是取正还是取负。
然后首先输出所有标记取正的下标,但是我们知道一个操作结束后后面的下标会变,所以我们设一个新的变量记录在某个位置之前操作了多少次,例如:我们设我们现在第i个位置,前面操作了cnt次,这样i的下标就应该因为操作而被迫变更了cnt次,但是观察样例的推断我们可以发现,在样例中,原本i = 2时,i = 2理当是正的,但是在最初我们全部将i = 2的情况标记为负了,所以这就是说,类推到所有情况,所有取正的下标,在原题i和i+1的
情况中,实际上取正的是i+1,所以对于取正的位置的下标,除了要减去cnt外,还要再减去1
最后我们讨论输出1的情况,我们相当我们吧所有取正的情况输出后,操作次数cnt,很可能(很大可能)并不到n-1,一方面是因为刚才我们没有输出1,但另一方面,存在cnt与n-1的差距不止1,这种情况说明在最后,在进行了全部的操作后,最后所有剩下的数不再进行取正操作,也就是说除了1之外全部取为了负数,例如: 1 2 3 4 5 6 ,除了1之外,2,3,4,5,6全部标成取负号,这意味着在这些操作中,所有的i全部取为1,所以我们就要输出
n-1-cnt个1,当然也可以是在所有在标记为取负的位置输出'1',但是我们上面说了因为2的符号强制取负的关系,下标除了减去cnt还要再减去1,但是1是不受影响的,原因非常简单:下标1在下标2之前,所以下标1不受下标2的影响
最后顺便批判一番!AC程序过不了样例系列!!!!!!
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn = ;
const int maxt = ;
const int quz = ;
int n, t;
int f[maxn][maxt];
int a[maxn];
int ans[maxn]; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} int main() {
memset(f, , sizeof(f));
n = read(), t = read();
for(int i = ; i <= n; ++i)
a[i] = read();
f[][a[] + quz] = ;
f[][a[] - a[] + quz] = -;
for(int i = ; i <= n; ++i)
for(int j = - + quz; j <= + quz; ++j) {
if(f[i - ][j] != ) {
f[i][a[i] + j] = ;
f[i][j - a[i]] = -;
}
}
int s = quz + t;
for(int i = n; i >= ; --i) {
ans[i] = f[i][s];
if(ans[i] == )
s -= a[i];
else if(ans[i] == -)
s += a[i];
}
int cnt = ;
for(int i = ; i <= n; ++i)
if(ans[i] == ) {
cout << i - cnt - << '\n';
cnt++;
}
for(int i = ; i <= n; ++i)
if(ans[i] == -)
cout << << '\n';
/* for(; cnt + 1 <= n - 1; cnt++)
cout << 1 << '\n';*/
return ;
}
POJ 1722 SUBTRACT的更多相关文章
- $2019$ 暑期刷题记录1:(算法竞赛DP练习)
$ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...
- poj动态规划列表
[1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...
- POJ 动态规划题目列表
]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 1322 ...
- [转] POJ DP问题
列表一:经典题目题号:容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1191,1208, 1276, 13 ...
- POJ动态规划题目列表
列表一:经典题目题号:容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1191,1208, 1276, 13 ...
- DP题目列表/弟屁专题
声明: 1.这份列表不是我原创的,放到这里便于自己浏览和查找题目. ※最近更新:Poj斜率优化题目 1180,2018,3709 列表一:经典题目题号:容易: 1018, 1050, 1083, 10 ...
- poj 1737 Connected Graph
// poj 1737 Connected Graph // // 题目大意: // // 带标号的连通分量计数 // // 解题思路: // // 设f(n)为连通图的数量,g(n)为非连通图的数量 ...
- poj 题目分类(1)
poj 题目分类 按照ac的代码长度分类(主要参考最短代码和自己写的代码) 短代码:0.01K--0.50K:中短代码:0.51K--1.00K:中等代码量:1.01K--2.00K:长代码:2.01 ...
- POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)
本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...
随机推荐
- 【题解】SDOI2008莎拉公主的困惑
挺有趣的恩:洛谷P2155 在纸上打打草稿,写出n!个数,从先往后,遇到不互质的就筛掉——发现一个奇妙的性质!:筛掉的次数.顺序好像是周期性出现的呢~ 而且更加妙妙的是,好像还是m!一轮..那么因为n ...
- BJOI2018
BJOI2018 省选挂完,是时候更一篇题解了.对于鬼畜结论题我只放结论不给证明,不要打我-- day1 二进制 试题描述 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不 ...
- phaser常用API总结
1. 游戏画布的尺寸 var width = game.width, height = game.height; 2. 中心点坐标 var game = new Phaser.Game(...); ...
- 【NOIP模拟赛】 permutation 数学(打表)
biubiu~~~ 这道题卡读题卡得很死......首先他告诉我们读循环的时候要顺着圈读,然后又说这个圈在数列上要以最大数开始读,而且以这样的循环的首数排序,得到的序列与原序列一样那么他就是可行序列, ...
- HDU 4417 划分树写法
Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...
- Bash 实例,第二部分
我们先看一下处理命令行自变量的简单技巧,然后再看看 bash 基本编程结构. 接收自变量 在 介绍性文章 中的样本程序中,我们使用环境变量 "$1" 来引用第一个命令行自变量.类似 ...
- keydown
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>无标 ...
- 《vue.js实战》练习---数字输入框组件
html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- java replace方法
一:前言 replace自己老是忘记参数是那个替换那个,自己就把replace方法全部给弄了一遍 二:内容 package org.replaceDemo; public class ReplaceD ...
- [转]使用 LDAP 组或角色限制访问,包含部分单点登录SSO说明
参考:http://www-01.ibm.com/support/knowledgecenter/api/content/SSEP7J_10.2.2/com.ibm.swg.ba.cognos.crn ...