题目大意:
有一个数列a[1]……a[n],每次可以对这个数列进行一次操作,操作为用a[i]-a[i+1]这一项替代a[i]和a[i+1]这两项,要求进行n-1次操作之后这个数列只剩下一个数字a[1]=目标数字,输出操作顺序
分析:
其实转换一下就会发现其实就是在每个数字前面添加‘+’or‘-’
这不就是背包么….
然后输出略有些懵…看了看题解才发现自己脑残了…其实对于每个+号处理完之后,剩下的减号就一直从前往后合并就好了…
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=100+5,maxm=10000+5;
int n,a[maxn],t,f[maxn][maxm*2],pre[maxn][maxm*2],sign[maxn],cnt;
signed main(void){
scanf("%d%d",&n,&t),t+=10000;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(f,0,sizeof(f));
f[1][a[1]+10000]=2;
f[2][a[1]-a[2]+10000]=1;
for(int i=3;i<=n;i++)
for(int j=0;j<=20000;j++)
if(f[i-1][j]){
if(j+a[i]<=20000)
f[i][j+a[i]]=2;
if(j-a[i]>=0)
f[i][j-a[i]]=1;
}
for(int i=n;i>=1;i--){
if(f[i][t]==2)
sign[i]=1,t-=a[i];
else
sign[i]=0,t+=a[i];
}
int tmp=0;
for(int i=2;i<=n;i++)
if(sign[i]==1)
cout<<i-1-tmp++<<endl;
for(int i=2;i<=n;i++)
if(sign[i]==0)
cout<<1<<endl;
return 0;
}
by >_< NeighThorn