[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 ...
随机推荐
- 如何吸引用户打开自己发送的EDM邮件
一般来说,邮件发送到用户的收件箱,但用户不一定会阅读.因为每个用户收到的邮件都很多.那么,究竟应该如何吸引读者打开自己的EDM邮件呢? 只有当用户认识并信任发件人的时候,此时邮件的打开率是最高的,可以 ...
- C# 内存建表备忘
#region=====建表===== DataSet dataSet; // 创建表 DataTable table = new DataTable("testTable"); ...
- ELK Stack 企业级日志收集平台
ELK Stack介绍 大型项目,多产品线的日志收集 ,分析平台 为什么用ELK? 1.开发人员排查问题,服务器上查看权限 2.项目多,服务器多,日志类型多 ELK 架构介绍 数据源--->lo ...
- SoapUI学习之SOAP和REST的区别
一.Soap和Rest的定义 SOAP(Simple Object Access Protocol 简单对象访问协议),用于在Web Service中把远程调用和返回封装成机器可读的格式化数据,事实上 ...
- python接口自动化:https请求,取消警告
实现代码如下: import requests r=requests.get('https://www.baidu.com',verify=False) rr=r.content.decode() p ...
- Java学习day5程序控制流程二
循环结构: 循环语句的四个组成部分:1.初始化部分(init_statement) 2.循环条件部分(test_exp) 3.循环体部分(body_statement) 4.迭代部分(after_st ...
- POJ-1502 MPI Maelstrom 迪杰斯特拉+题解
POJ-1502 MPI Maelstrom 迪杰斯特拉+题解 题意 题意:信息传输,总共有n个传输机,先要从1号传输机向其余n-1个传输机传输数据,传输需要时间,给出一个严格的下三角(其实就是对角线 ...
- java视频资源
1.Java基础阶段 尚学堂_刘凯立_JavaSE基础视频 http://pan.baidu.com/s/1geCoY11 尚学堂_高淇_Java300集视频教程 https://pan.baidu. ...
- 1.Dockerfile
1.docker build docker build 这个动作有一个context 上下文的概念 docker build -f /path/to/a/Dockerfile .这个动作 通过 -f ...
- Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩阵快速幂)
题目传送门 题意: 一个魔法水晶可以分裂成m个水晶,求放满n个水晶的方案数(mol1e9+7) 思路: 线性dp,dp[i]=dp[i]+dp[i-m]; 由于n到1e18,所以要用到矩阵快速幂优化 ...