背包。。。差不多。。QWQ
设f[i]为达到差值为i的状态需要多少次,那就很显然了; 注意区分正负不同的代价的循环方向
技巧:如果不想改负数的话,那可以移动一下数组下标,用一个新的指针指向原来的数组
#include<cstdio> #include<iostream> #include<cstring> #define R register int const int lim=6000; using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,sum; int s[1010],d[13010],*f=d+lim; inline int abs(int x) {return x>0?x:-x;} signed main() { n=g(); for(R i=1,a,b;i<=n;++i) a=g(),b=g(),s[i]=a-b,sum+=s[i]; memset(d,0x3f,sizeof(d)); f[sum]=0; for(R i=1;i<=n;++i) if(s[i]<0) for(R j=lim;j>=-lim;--j) f[j]=min(f[j],f[j+2*s[i]]+1); else if(s[i]>0) for(R j=-lim;j<=lim;++j) f[j]=min(f[j],f[j+2*s[i]]+1); for(R i=0;i<=abs(sum);++i) if(min(f[i],f[-i])!=0x3f3f3f3f) {printf("%d ",min(f[i],f[-i])); break;} }
2019.04.29