title
POJ 1722
CH POJ1722
Description
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.
Input
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
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.
Sample Input
5 4
12
10
4
3
5
Sample Output
2
3
2
1
Source
analysis
请移步到昕泽学长的blog处
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=110,maxt=2e4+100,quz=10005;
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
int f[maxn][maxt],a[maxn],ans[maxn];
int main()
{
int n,t;
read(n);read(t);
for (int i=1; i<=n; ++i)
read(a[i]);
f[1][a[1]+quz]=1;
f[2][a[1]-a[2]+quz]=-1;
for (int i=3; i<=n; ++i)
for (int j=-10000+quz; j<=10000+quz; ++j)
if (f[i-1][j])
f[i][a[i]+j]=1,f[i][j-a[i]]=-1;
int s=quz+t;
for (int i=n; i>=2; --i)
{
ans[i]=f[i][s];
if (ans[i]==1)
s-=a[i];
else if (ans[i]==-1)
s+=a[i];
}
int cnt=0;
for (int i=2; i<=n; ++i)
if (ans[i]==1)
{
printf("%d\n",i-cnt-1);
++cnt;
}
for (int i=2; i<=n; ++i)
if (ans[i]==-1)
puts("1");
return 0;
}