您的位置:首页 > 其它

UVA 562 Dividing coins 分硬币(01背包,简单变形)

2015-05-03 17:53 537 查看
题意:一袋硬币两人分,要么公平分,要么不公平,如果能公平分,输出0,否则输出分成两半的最小差距。

思路:将提供的整袋钱的总价取一半来进行01背包,如果能分出出来,就是最佳分法。否则背包容量为一半总价的包能装下的硬币总值就是其中一个人能分得的最多的钱了,总余下的钱减去这包硬币总值。(只需要稍微考虑一下总值是奇数/偶数的问题)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
const int N=100000;
int w
, dp
;

void cal(int n, int cnt)
{
int m;
if(cnt&1==1)    m = (cnt>>1) + 1;//奇数
else            m=cnt>>1;

for(int i=0; i<n; i++)
for(int j=m; j>=w[i]; j--)
dp[j]=max( dp[j-w[i]]+w[i], dp[j] );

if(cnt&1==1)//奇数
{
if(dp[m]==m)    cout<<"1"<<endl; //最公平
else    cout<<cnt-dp[m]-dp[m]<<endl;
}
else
{
if(dp[m]==m)    cout<<"0"<<endl;  //最公平
else            cout<<cnt-dp[m]-dp[m]<<endl;
}

}

int main()
{
//freopen("input.txt","r",stdin);
int t, n, cnt;
cin>>t;
while(t--)
{
memset(dp, 0, sizeof(dp));
memset(w, 0, sizeof(w));
cin>>n;
cnt=0;
for(int i=0; i<n; i++)
{
scanf("%d",&w[i]);
cnt+=w[i];
}
if(n==0)
cout<<"0"<<endl;
else if(n==1)
cout<<w[0]<<endl;
else if(n==2)
cout<<abs(w[0]-w[1])<<endl;
else
cal(n, cnt);
}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: