UVA 10482 The Candyman Can

来源:互联网 发布:php实现视频文件上传 编辑:程序博客网 时间:2024/06/05 22:38

题目大意:给许多硬币,分给三个人,要求输出拿钱最多者与拿钱最少者差的最小值。

解题策略:思路同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;}