[POJ1772] Substract
问题描述
We are given a sequence of N positive integers a = [a1, a2, ..., aN] on which we can perform contraction operations.
One contraction operation consists of replacing adjacent elements ai and ai+1 by their difference ai-ai+1. For a sequence of N integers, we can perform exactly N-1 different contraction operations, each of which results in a new (N-1) element sequence.Precisely, let con(a,i) denote the (N-1) element sequence obtained from [a1, a2, ..., aN] by replacing the elements ai and ai+1 by a single integer ai-ai+1:
con(a,i) = [a1, ..., ai-1, ai-ai+1, ai+2, ..., aN]
Applying N-1 contractions to any given sequence of N integers obviously yields a single integer.
For example, applying contractions 2, 3, 2 and 1 in that order to the sequence [12,10,4,3,5] yields 4, since :
con([12,10,4,3,5],2) = [12,6,3,5]
con([12,6,3,5] ,3) = [12,6,-2]
con([12,6,-2] ,2) = [12,8]
con([12,8] ,1) = [4]
Given a sequence a1, a2, ..., aN and a target number T, the problem is to find a sequence of N-1 contractions that applied to the original sequence yields T.
输入格式
The first line of the input contains two integers separated by blank character : the integer N, 1 <= N <= 100, the number of integers in the original sequence, and the target integer T, -10000 <= T <= 10000. The following N lines contain the starting sequence : for each i, 1 <= i <= N, the (i+1)st line of the input file contains integer ai, 1 <= ai <= 100.
输出格式
Output should contain N-1 lines, describing a sequence of contractions that transforms the original sequence into a single element sequence containing only number T. The ith line of the output file should contain a single integer denoting the ith contraction to be applied. You can assume that at least one such sequence of contractions will exist for a given input.
样例输入
5 4
12
10
4
3
5
样例输出
2
3
2
1
题目大意
给定一个序列a,每次可以选择两个数a[i]和a[i+1],从序列中将这两个数替换为一个数a[i]-a[i+1]。求最少的操作方案使最后剩下的数为给定的t。
题解
假设我们有三个数i,j,k,如果我们首先将j和k合并,得到了i和j-k。接下来把剩下两个数合并,最后的结果为i-(j-k)=i-j+k。换一种方式,首先合并i和j,得到i-j和k,再合并两个数,得到的最后结果为i-j-k。容易发现,最后的结果其实是由序列中的数通过加和减的操作得来的。那么问题就转化为对一个序列加入加号和减号,使其最后计算出的结果为t。由于最后要求输出方案,我们可以利用动态规划来完成。设\(f[i][j]\)表示在第i个数、前面计算结果为j时第i个数为加还是减。那么状态转移方程为:
\]
其中1表示为加号,0表示为减号。那么我们怎么推出方案呢?已知最后的结果为t,那么可以用倒推法,一步一步地推出方案。假设当前结果为s,如果\(f[i][s]\)为1,说明这个数取正,同时使s减去a[i]。反之取负,同时s加上a[i]。如此往复。但怎么推出是第几个呢?我们不妨这样做:首先把所有加号处理完,然后一起输出减号。因为如果最后只剩减号的话,可以一直输出1而没有对位置的影响。那么现在考虑加号的决策。如果一个值取得为加号,那么在此之前这个数一定是被合并过的。记前面进行过的操作次数为cnt。那么这个数的位置一共被向前推移了cnt次。但按照输出规则,应当输出它的前一个数(前一个数和该数合并)。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 102
#define M 10002
using namespace std;
const int T=10000;
int n,t,i,j,a[N],f[N][M*2],opt[N];
int main()
{
cin>>n>>t;
for(i=1;i<=n;i++) cin>>a[i];
memset(f,-1,sizeof(f));
f[1][a[1]+T]=1;
f[2][a[1]-a[2]+T]=0;
for(i=3;i<=n;i++){
for(j=0;j<=2*T;j++){
if(f[i-1][j]!=-1){
f[i][j+a[i]]=1;
f[i][j-a[i]]=0;
}
}
}
j=t+T;
for(i=n;i>=1;i--){
if(f[i][j]==1){
opt[i]=1;
j-=a[i];
}
else if(f[i][j]==0){
opt[i]=0;
j+=a[i];
}
}
int cnt=0;
for(i=2;i<=n;i++){
if(opt[i]==1){
cout<<i-cnt-1<<endl;
cnt++;
}
}
for(i=2;i<=n;i++){
if(opt[i]==0) cout<<"1"<<endl;
}
return 0;
}
[POJ1772] Substract的更多相关文章
- 用户字符串操作,这里面包括字符串的decode、encode、substract等等操作
工具类描述:用户字符串操作,这里面包括字符串的decode.encode.substract等等操作 package cn.hgnulb; import java.io.UnsupportedEnco ...
- POJ1722 算法竞赛进阶指南 SUBSTRACT减操作
原题连接 题目描述 给定一个整数数组\(a_1,a_2,-,a_n\). 定义数组第 i 位上的减操作:把\(a_i\)和\(a_{i+1}\)换成\(a_i - a_{i+1}\). 用con(a, ...
- Java基础知识【下】( 转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608360 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- 【原】Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令
<Learning Spark>这本书算是Spark入门的必读书了,中文版是<Spark快速大数据分析>,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足 ...
- Junit的使用
Junit是用于编写单元测试的框架.对于已经写好的函数,可以使用Junit生成单元测试代码. 自己的环境是:Linux Java环境是:JDK1.7 IDE:Eclipse Java EE IDE f ...
- tensorflow学习
tensorflow安装时遇到gcc: error trying to exec 'as': execvp: No such file or directory. 截止到2016年11月13号,源码编 ...
- 仿window系统自带的日期差计算器类
public class MonthSubstract { /// <summary> /// 日期差之月份 /// </summary> public int Months ...
- [转]在Eclipse中使用JUnit4进行单元测试(初级篇)
首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...
- [大数据之Spark]——Transformations转换入门经典实例
Spark相比于Mapreduce的一大优势就是提供了很多的方法,可以直接使用:另一个优势就是执行速度快,这要得益于DAG的调度,想要理解这个调度规则,还要理解函数之间的依赖关系. 本篇就着重描述下S ...
随机推荐
- 使用JS将图片转为Base64
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- xml基础之二(XML结构【2】)DTD文档模版
xml基础之二(XML结构[2])DTD文档模版 xml 模板 文档结构 我们知道XML主要用于数据的存储和传输,所以无论是自定义还是外部引用DTD模板文档,都是为了突出数据的存储规范.DTD(文档 ...
- Memcache和Redis复习总结
Memcache Memcache是一个高性能的分布式的内存对象缓存系统,主要是用来缓存从MySQL数据库中查询的数据,减少对mysql数据库的压力. Memcache的工作流程: 当用户发生一个动态 ...
- codeforces 668C - Little Artem and Random Variable
题目链接:http://codeforces.com/contest/668/problem/C --------------------------------------------------- ...
- Log4net记录日志到本地或数据库
OperatorLog /****** Object: Table [dbo].[OperatorLog] Script Date: SET ANSI_NULLS ON GO SET QUOTED_I ...
- JS text节点无innerHTML
在线预览 text节点无innerHTML这个属性!!! 如果直接修改text节点的属性(data,nodeValue,textContent),或者使用js原生的修改text节点的内容的方法都会将H ...
- R语言平均值,中位数和众数
R语言平均值,中位数和众数 R中的统计分析通过使用许多内置函数来执行的.这些函数大部分是R基础包的一部分.这些函数将R向量与参数一起作为输入,并在执行计算后给出结果. 我们在本章中讨论的是如何求平均值 ...
- C# Thread3——前台线程后台线程
默认情况下,显示创建的线程都是前台线程,进程会等待内部所有的前台线程执行完才会结束退出 1.默认创建的线程都是前台线程 2.进程会等待所有的前台线程执行完而结束,如果还存在后台线程则会强行中断并且退出 ...
- python正则表达式整理
正则表达式在处理字符串时很大的作用,爬虫中也经常用到,下面就将一些常用正则表达式做一整理记录,方便以后查看. ^d 表示匹配以d开头的字符串 . 表示匹配任意字符串 * 表示前面 ...
- mysql5.7插入数据报错 Incorrect integer value
mysql5.7插入字符串为空的时候取出来的值设置为null