• UVALive5583 UVA562 Dividing coins


    Regionals 1996 >> Europe - Northwestern

    问题链接UVALive5583 UVA562 Dividing coins

    问题简述:输入测试用例数n,每个测试用例包括金币的数量m和m个正整数是金币的币值。将这些金币分为两堆,使得其差值最小,求最小的差值。

    问题分析:可以用0/1背包的动态规划方法来解决这个问题。将背包的容量设为所有金币币值之和的一半,将这一堆金币尽可能多地放入背包即可。再计算一下差值即可。

    0/1背包动态规划法的递归式为f(j,X),其中j=0,1,2,...,n-1为物品(共n个物品),X是背包的载重量。f(j,X)的含义为:当背包载重为X,可供选择的物品为0,1,2,...,j时的最优值。具体式子如下:

    f(-1,X)=-(X<0),f(-1,X)=0(X>=0)

    f(j,X)=max{f(j-1,X), f(j-1(X-wj)+pj} 0<=j<n,wj为第j件物品重量,pj为第j件物品收益。

    程序说明程序中,用二维数组dp[][]来存放递推函数的值,比较浪费存储空间,应该使用STL构筑一个稀疏矩阵来存储比较合理。

    另外,wj=coin[j]即币值,pj=coin[j]即币值,一种特例情况。程序逻辑实际上是套用0/1背包递推函数。

    AC的C语言程序如下:

    /* UVALive5583 UVA562 Dividing coins */
    
    #include <stdio.h>
    #include <memory.h>
    
    #define MAX(x, y) (((x)>(y))?(x):(y))
    
    #define MAXN 100
    
    int dp[MAXN+1][MAXN * 500];
    
    int main(void)
    {
        int t, m, coin[MAXN+1], sum, sum2, i, j;
    
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &m);
    
            memset(coin, 0, sizeof(coin));
            memset(dp, 0, sizeof(dp));
    
            sum = 0;
            for(i=1; i<=m; i++) {
                scanf("%d", &coin[i]);
                sum += coin[i];
            }
    
    
            sum2 = sum / 2;
            for(i=1; i<=m; i++)
                for(j=0; j<=sum2; j++)
                    if(j >= coin[i])
                        dp[i][j] = MAX(dp[i - 1][j], (dp[i - 1][j - coin[i]] + coin[i]));
                    else
                        dp[i][j] = dp[i - 1][j];
    
            printf("%d
    ", sum - dp[m][sum2] - dp[m][sum2]);
        }
    
        return 0;
    }


  • 相关阅读:
    5G终端测试 FOTA功能
    利尔达 UIS8910DM 模组的 发送短信TEXT格式
    利尔达 UIS8910DM 模组的 发送短信PDU格式
    altera原厂 cyclone V开发板使用记录
    【3】TensorFlow光速入门-训练及评估
    【2】TensorFlow光速入门-数据预处理(得到数据集)
    【1】TensorFlow光速入门-tensorflow开发基本流程
    【0】TensorFlow光速入门-序
    DbHelperSQL
    Git——简单的分支规范
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564410.html
Copyright © 2020-2023  润新知