UVA 562 Dividing coins
2012-04-09 16:50
176 查看
题目大意:给你若干硬币,让你分成两份,使其绝对值之差尽量的小。
很容易想到,我们需要枚举出这些硬币可能凑出的所有面值,那么,怎么去算出这些硬币可能凑出的面值就是我们需要解决的问题了。
令dp[i]数组来保存是否可以凑出i的面值的结果。可以为1,否则为0.sum为这些硬币的面值之和。
显然dp[0]=1,有一份一分钱都没有事肯定可以的。那么dp[sum]=1,有一份可以囊括所有的硬币。
那么既然dp[0]是可以的,那么dp[0+coin[j]]也一定可以凑出来,同理dp[sum-coin[j]]也是可以的;如此推广下去,dp[coin[j]]可以,dp[coin[j]+coin[k]]也可以………………我们获得的可以凑出来的面值数量会越来越多。这样的算法复杂度为n的平方吧。
最后,我们去寻找距离总面值数一半的(sum/2)差值最小的那个数j,那么我们最后输出的结果显然是sum-j*2。
下面贴代码
View Code
很容易想到,我们需要枚举出这些硬币可能凑出的所有面值,那么,怎么去算出这些硬币可能凑出的面值就是我们需要解决的问题了。
令dp[i]数组来保存是否可以凑出i的面值的结果。可以为1,否则为0.sum为这些硬币的面值之和。
显然dp[0]=1,有一份一分钱都没有事肯定可以的。那么dp[sum]=1,有一份可以囊括所有的硬币。
那么既然dp[0]是可以的,那么dp[0+coin[j]]也一定可以凑出来,同理dp[sum-coin[j]]也是可以的;如此推广下去,dp[coin[j]]可以,dp[coin[j]+coin[k]]也可以………………我们获得的可以凑出来的面值数量会越来越多。这样的算法复杂度为n的平方吧。
最后,我们去寻找距离总面值数一半的(sum/2)差值最小的那个数j,那么我们最后输出的结果显然是sum-j*2。
下面贴代码
View Code
#include <iostream> #include <cstring> using namespace std; int coin[101]; int dp[101000]; int main() { int ncase,sum,i,j,m; cin>>ncase; while(ncase--) { memset(dp,0,sizeof(dp)); sum = 0; cin>>m; for(i = 1;i <= m;i++) { cin>>coin[i]; sum += coin[i]; } dp[0] = 1; for(i = 1;i <= m;i++) for(j = sum;j >= coin[i];j--) if(dp[j - coin[i]]) dp[j] = 1; for(i = sum / 2;i >= 0;i--) if(dp[i]) { j = i; break; } /*for(i = 0;i <= sum;i++) cout<<i<<"->"<<dp[i]<<" "; cout<<endl;*/ cout<<sum - 2 * j<<endl; } return 0; }
相关文章推荐
- uva_562 Dividing coins
- uva 562 Dividing coins
- UVa 562 - Dividing coins
- Uva-562- Dividing coins
- UVa 562 Dividing coins
- UVA 562 Dividing coins
- UVA 562 - Dividing coins
- UVA 562 Dividing coins 01背包 Commencel
- UVA 562 Dividing coins
- UVA 562 - Dividing coins
- UVA 562 - Dividing coins
- UVA - 562 - Dividing coins (01背包)
- UVa 562 - Dividing coins
- UVA - 562 Dividing coins
- uva 562 Dividing coins
- uva 562 - Dividing coins
- UVA 562 Dividing coins
- UVA 562 - Dividing coins
- UVA 562 Dividing coins --01背包的变形
- UVA 562 Dividing coins