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;}