//============================================================================ // Name : 100题之32求两个序列a和b,交换ab的元素,使得ab之间的差最小.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; int n; int a[100]; int b[100]; int f[100][80000]; int path[100][80000]; int C[100]; int numa; int numb; void print(int j,int k) { if(j<=0||k<=0) return; if(path[j][k]==0) return; print(j-1,f[j][k]-C[path[j][k]]); if(path[j][k]>n) numb++; else numa++; cout<<C[path[j][k]]<<" "; } void compute() { int sum=0; for(int i=1;i<=n*2;i++) { if(i<=n) { C[i]=a[i]; sum+=a[i]; } else { C[i]=b[i-n]; sum+=b[i-n]; } } sum/=2; cout<<sum<<endl; for(int i=1;i<=2*n;i++) { for(int k=n;k>=1;k--) { if(k<=i) { for(int j=sum;j>=C[i];j--) { //cout<<"C["<<i<<"] is "<<C[i]<<endl; if(f[k][j]<f[k-1][j-C[i]]+C[i]) { f[k][j]=f[k-1][j-C[i]]+C[i]; path[k][j]=i; } // cout<<"path["<<k<<"]["<<j<<"]="<<path[k][j]<<endl; // cout<<"f["<<k<<"]["<<j<<"]="<<f[k][j]<<endl; } } } } for(int k=1;k<=n;k++) for(int j=1;j<=sum;j++) { cout<<"path["<<k<<"]["<<j<<"]="<<path[k][j]<<endl; cout<<"f["<<k<<"]["<<j<<"]="<<f[k][j]<<endl; } cout<<f[n][sum]<<endl; print(n,sum); int num=numa>numb?numa:numb; cout<<endl<<n-num<<endl; } int main() { a[1]=1; a[2]=1; a[3]=2; a[4]=3; a[5]=29; //a[6]=30; b[1]=30; b[2]=210; b[3]=232; b[4]=12311; b[5]=12312; //b[6]=40; n=5; compute(); return 0; }