您的位置:首页 > 其它

UVA 10482 The Candyman Can

2013-03-29 15:31 2326 查看
题目大意:给许多硬币,分给三个人,要求输出拿钱最多者与拿钱最少者差的最小值。

解题策略:思路同Dividing Coins,定义二维数组dp[i][j],表示第一个人拿i钱,第二个人拿j钱,第三个人呢?当然硬币总和(sum)-i-j,

当前方案可施行,dp=1,否则为0,运用减唯的思想;

/*
UVA 10482 The Candyman Can
AC by J.Dark
ON 2013/3/29
Time 0.192s
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int coinmaxn = 35;
const int maxn = 650;
int coinNum, sum, coin[coinmaxn];
int value[maxn][maxn];

void input(){
sum = 0;
for(int i=1; i<=coinNum; i++){
cin >> coin[i];
sum += coin[i];
}
}

//返回每组分配方案拿钱最多-拿钱最少
int searchMin(int a, int b, int c){
return max(max(a,b), c)- min(min(a,b), c);
}

int solve(){
int minAns = 999999;
memset(value, 0, sizeof(value));
value[0][0] = 1;  //第三个人钱全拿走
for(int i=1; i<=coinNum; i++){
for(int j=sum; j>=0; j--){
for(int k=sum; k>=0; k--){
if(value[j][k]){
value[j+coin[i]][k] = 1;
value[j][k+coin[i]] = 1;
}
}
}
}
for(int j=0; j<=sum; j++){
for(int k=0; k<=sum; k++){
if(value[j][k]) //若分配方案存在,枚举最小值
minAns = min(minAns, searchMin(j, k, sum-j-k));
}
}
return minAns;
}

void output(int tc){
printf("Case %d: %d\n", tc, solve());
}
///////////////////////////////////////
int main(){
int testCase;
while(cin >> testCase)
{
for(int i=1; i<=testCase; i++){
cin >> coinNum;
input();
output(i);
}
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: