题目大意:每个瓶子有一定的容积,以及一定的水量,问最少几个瓶子装满所有水,在此基础上还要最小化移动水的体积
第一问用贪心直接求
第二问转化成背包问题
设dp[i][j]表示前i桶水总容积为j的最多水量,这些水是不需要转移的
用总体积减去最多水量即为答案
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 bool cmp(int x,int y) {return x>y;} 6 int n,lft,num,tot,ans; 7 int a[101],b[101],d[101],dp[101][10001]; 8 int main() 9 { 10 cin>>n; 11 for(int i=1;i<=n;i++) cin>>a[i],lft+=a[i]; 12 for(int i=1;i<=n;i++) cin>>b[i],d[i]=b[i]; 13 sort(d+1,d+1+n,cmp); 14 memset(dp,128,sizeof(dp)); 15 dp[0][0]=0; 16 for(int i=1;i<=n;i++) 17 { 18 tot+=d[i]; 19 if(tot>=lft) 20 { 21 num=i; 22 break; 23 } 24 } 25 for(int i=1;i<=n;i++) 26 for(int j=tot;j>=b[i];j--) 27 for(int k=1;k<=num;k++) 28 dp[k][j]=max(dp[k][j],dp[k-1][j-b[i]]+a[i]); 29 for(int i=lft;i<=tot;i++) ans=max(ans,dp[num][i]); 30 cout<<num<<" "<<lft-ans<<endl; 31 return 0; 32 }