Please help the poor donkey!
Time Limit : 1000 MS | Memory Limit : 65536 KB
Submits : 27 | Solved : 3
Description
A donkey is on his way home with many goods hanging on the two side of his back ,tired and thirsty . What a poor donkey ! What's worse , the total weight of the goods on each side of his back doesn't have the same value , which makes the poor donkey much more difficult to keep balance .Now I should to help the poor donkey move some goods from one side to another to ease his burden . I want to minimize the difference of the total weight between the two sides .Of course I'm very lazy ,could you tell me the minimum number of the goods that I need to move to minimize the difference of the total weight betwoon the two sides. If you tell me the correct answer , I will give you an 'AC' !
Input
Input contains multiple test cases. The first line of each test cases contains two integers n and m , n indicates the number of the goods hanging on the left side of the donkey, m indicates the number of the goods hanging on the right side of the donkey.(0<n+m<=1000)
The second line of the test case contains n integers indicating the weight of the n goods on the left side .
The third line contains m integers indicating the weight of the m goods on the right .
Output
Output the minimum number of the goods that I need to move .
Sample Input
1 3 5 4 2 1
Sample Output
1
#include<cstdio>
const int N=1001;
int a[N],dp[N][N<<2];
int min(int a,int b){
if(a==-1)return b;
if(b==-1)return a;
return a<b?a:b;
}
int abs(int a){return a<0?-a:a;}
int main(){
int n,m,i,j,lsum,sum;
while(~scanf("%d%d",&n,&m)){
lsum=0,m+=n;
for(i=1;i<=n;i++)scanf("%d",a+i),lsum+=a[i];
sum=lsum;
for(;i<=m;i++)scanf("%d",a+i),sum+=a[i];
for(i=0;i<=sum;i++)dp[0][i]=-1;
dp[0][lsum]=0;
for(i=1;i<=m;i++){
for(j=0;j<=sum;j++)dp[i][j]=dp[i-1][j];
for(j=0;j<=sum;j++)if(dp[i-1][j]!=-1){
if(i>n)dp[i][j+a[i]]=min(dp[i][j+a[i]],dp[i-1][j]+1);
else dp[i][j-a[i]]=min(dp[i][j-a[i]],dp[i-1][j]+1);
}
}
int ans;
for(i=sum>>1;i>=0;i--){
if(dp[m][i]!=-1||dp[m][sum-i]!=-1){ans=min(dp[m][i],dp[m][sum-i]);break;}
}
printf("%d\n",ans);
}
return 0;
}
滚动数组
#include<cstdio>
const int N=1001;
int a[N],dp[2][N<<2];
int min(int a,int b){
if(a==-1)return b;
if(b==-1)return a;
return a<b?a:b;
}
int abs(int a){return a<0?-a:a;}
int main(){
int n,m,i,j,lsum,sum;
while(~scanf("%d%d",&n,&m)){
lsum=0,m+=n;
for(i=1;i<=n;i++)scanf("%d",a+i),lsum+=a[i];
sum=lsum;
for(;i<=m;i++)scanf("%d",a+i),sum+=a[i];
for(i=0;i<=sum;i++)dp[0][i]=-1;
dp[0][lsum]=0;
int now=0;
for(i=1;i<=m;i++){
now^=1;
for(j=0;j<=sum;j++)dp[now][j]=dp[now^1][j];
for(j=0;j<=sum;j++)if(dp[now^1][j]!=-1){
if(i>n)dp[now][j+a[i]]=min(dp[now][j+a[i]],dp[now^1][j]+1);
else dp[now][j-a[i]]=min(dp[now][j-a[i]],dp[now^1][j]+1);
}
}
int ans;
for(i=sum>>1;i>=0;i--){
if(dp[now][i]!=-1||dp[now][sum-i]!=-1){ans=min(dp[now][i],dp[now][sum-i]);break;}
}
printf("%d\n",ans);
}
return 0;
}