POJ 1722 SUBTRACT

Description (Special Judge

We are given a sequence of Npositive integers a = [a1, a2, ..., aN] on which we can perform contractionoperations.
One contraction operation consists of replacing adjacent elements ai and ai+1by their difference ai-ai+1. For a sequence of N integers, we canperform exactly N-1 different contraction operations, each of which results ina 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 singleinteger 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 yieldsa 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 finda sequence of N-1 contractions that applied to the original sequence yields T.

Input

The first line of the inputcontains two integers separated by blank character : the integer N, 1 <= N<= 100, the number of integers in the original sequence, and the targetinteger 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

Output should contain N-1lines, describing a sequence of contractions that transforms the originalsequence into a single element sequence containing only number T. The ith lineof the output file should contain a single integer denoting the ithcontraction to be applied.
You can assume that at least one such sequence of contractions will exist for agiven input.

Sample Input

5 4

12

10

4

3

5

Sample Output

2

3

2

1

 

 

题目简介:给N个数,例12,10,4,3,5。然后每次给你处理数在数列中的位置数,然后就用该数减去后面一个数,一直这样,直到得到T。[12,10,4,3,5],2表示处理第二个数,即10,用10减去4,得到[12,6,3,5],然后继续。[12,6,3,5] ,3,表示处理第三个数,即3,用3减去5,得到-2。继续。直到得到4。

方法:动态规划。可以看作是一串数之中添加+、-。除了第一个数和第二个数之间必须是减号连接,其他之间可加可减。之后就先处理加号。用f[i][j]记录下处理完前i个数得到j,f[i][j]存由f[i-1][]是加还是减得到f[i][j]的。

 

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int f[110][20010], num[110], p[110];//f[i][j],表示处理了前i个数得到结果j。f[i][j]中保存的是由加还是减得到的。
int main()
{
	int N, T;

	scanf("%d%d",&N,&T);
	for(int i = 1;i<=N;i++)
	{
		scanf("%d",&num[i]);
	}

	memset(f,-1,sizeof(f));
	//加为1,减为0.显然第一个数和第二个数之间必须为减
	f[1][num[1]+10000] = 1;
	f[2][num[1] - num[2]+10000] = 0;

	for(int i = 3;i<=N;i++)
	{
		for(int j = 0;j<=20000;j++)
		{
			if(f[i - 1][j]!=-1)
			{
				f[i][j + num[i]] = 1;
				f[i][j - num[i]] = 0;
			}
		}
	}

	for(int i = N, j = T + 10000;i>=1;i--)
	{
		if(f[i][j]==1)
		{
			p[i] = 1;
			j -= num[i];
		}
		else if(f[i][j]==0)
		{
			p[i] = 0;
			j += num[i];
		}
	}

	int count = 0;
	//先处理加号,加号可以看作是 -(b-c)
	for(int i = 2;i<=N;i++)
	{
		if(p[i]==1)
		{
			printf("%d\n",i - 1 - count);//看作是num[i]和num[i+1]被num[i]-num[i+1]取代了。
			count++;
		}
	}

	for(int i = 2;i<=N;i++)
	{
		if(p[i]==0)
		{
			printf("1\n");//开始没想通怎么输出。后来发现,处理完加号之后,减号的处理顺序无关紧要了,可以每次都是处理第一个数。
		}
	}

	system("pause");
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值