标签:int return 10000+ 状态 数字 判断 win name cout
//f[i,cnt] 表示前i个数字和为cnt
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110,M=200020;
int hh=10000;//hh是我们的下标偏移量
int n,t,f[N][M],a[N],ans[N];
void solve()
{
f[1][a[1]+hh]=1;//a[1]必然是正数
f[2][a[1]-a[2]+hh]=-1;//a[2]必然是
for(int i=3;i<=n;i++)
for(int j=-10000+hh;j<=10000+hh;j++)
//前i-1个数字可以组成的和,判断是否可以进行状态转移
if(f[i-1][j])
{
f[i][a[i]+j]=1;//表示第i个数字前为+号,就说明在这一位进行了减操作
f[i][j-a[i]]=-1;//表示第i个数字前为-号,就说明在i-1位进行了减操作
}
int s=hh+t;
for(int i=n;i>=2;i--)//回溯,确定+-号
{
//判断第i个数字前的符号
ans[i]=f[i][s];
//如果为1,那么就是+的
if(ans[i]==1)
s-=a[i];
else if(ans[i]==-1)
s+=a[i];
}
//如果这一位为1,那么就说明在前一位进行cut操作
//那么前一位前一位的前一位再进行时,就会变成+号
int cnt=0;
for(int i=2;i<=n;i++)
if(ans[i]==1)
{
cout<<i-cnt-1<<endl;
cnt++;
}
//如果是-1,那么就说明在1这一位进行了操作
for(int i=2;i<=n;i++)
if(ans[i]==-1)
cout<<1<<endl;
}
int main()
{
cin>>n>>t;
for(int i=1;i<=n;i++)
cin>>a[i];
solve();
return 0;
}
标签:int return 10000+ 状态 数字 判断 win name cout
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12604546.html